2011-04-17 76 views
0


我目前正在C#中使用VariableWatcher類。
我想要做的是在每次將變量更改爲特定值時引發一個事件。
例如:我有一個bool a,這是錯誤的。我將它傳遞給VariableWatcher類,並將其與應該引發事件的值true一起傳遞給VariableWatcher類。
我已經提出瞭解決這個問題的方法,但我顯然誤解了關於裝箱/取消裝箱的一些觀點。
在C中存儲對象的引用#

這是我的代碼:

public class ValueWatch 
    { 
    public delegate void ValueTriggeredD(string ID, string valuename, object source); 
    public event ValueTriggeredD ValueTriggered; 

    Dictionary<string, object[]> LookUp = new Dictionary<string, object[]>(); //Key = ID, Value[0] = PropertyName, Value[1] = ObjTrigger, Value[2] = ObjWatch 
    Timer ttt; 

    public void Initialize() 
    { 
     ttt = new Timer(new TimerCallback(CB_T), null, 0, 50); 
    } 
    void CB_T(object o) 
    { 
     if (LookUp.Count > 0) 
     { 
      foreach (KeyValuePair<string, object[]> kvp in LookUp) 
      { 
       Type tp = kvp.Value[2].GetType(); 
       FieldInfo inf = tp.GetField((string)kvp.Value[0]); 
       if (inf != null) 
       { 
        object curval = inf.GetValue(kvp.Value[2]); 
        if (curval == kvp.Value[1]) 
        { 
         if (ValueTriggered != null) 
          ValueTriggered(kvp.Key, (string)kvp.Value[0], kvp.Value[2]); 
        } 
       } 
      } 
     } 
    } 
    public void StartWatching(string ID, object ListObj, object ValueForTrigger, string PropertyName) 
    { 
     if (LookUp.ContainsKey(ID)) 
      System.Diagnostics.Debug.Print("already there"); 
     else 
     { 
      LookUp.Add(ID, new object[] { PropertyName, ValueForTrigger, ListObj }); 
     } 
    } 
    public void StopWatching(string ID) 
    { 
     LookUp.Remove(ID); 
    } 
} 

我的問題是:爲什麼存儲在該值的對象[2]而不是當我改變它的變化?

實施例:

bool b = false; 
valueWatch.ValueTriggered += new ValueTriggeredD(this.VT); 
valueWatch.StartWatching("ID1", this, true, "b"); 
... 
b = true; 
... 
void VT(string ID, string VN, object Source) 
{ 
    //Never triggered 
} 
+5

你也忘了問你的問題... – Oded 2011-04-17 13:39:10

+0

Ooops,對不起 - 編輯:) – alex 2011-04-17 13:48:08

+1

什麼是重點這個?爲什麼不只是在setter調用某種ValueChanged()方法的時候創建一個屬性? – Kon 2011-04-17 13:53:57

回答

1

這就是正確的。它永遠不會觸發。當你拳擊有價值的類型時,你實際上會製作一份價值的副本並將其放入內存中。所以當你改變變量的值時,你並沒有改變盒裝值。其中浮現在腦海中的第一件事 - 使用不安全的上下文拳擊變量地址但不幸的是.NET並不支持指針的拳擊(from MSDN):

指針類型不從object繼承和指針類型之間不存在轉換目的。另外,裝箱和拆箱不支持指針。但是,您可以在不同的指針類型之間以及指針類型和整型之間進行轉換。

所以你唯一的可能的方式 - 使用不安全的環境和存儲void*下面所有變量的地址:

 unsafe 
     { 
      bool test = false; 
      bool* adr = &test; 

      void* testObj = adr; 
      test = true; 
      Console.WriteLine("native test's value is" + test.ToString()); 
      Console.WriteLine("unboxed test's value is" + (*((bool*)testObj)).ToString()); 
     } 

但因爲它在評論中提到的,爲什麼不實現事件將觸發時財產已經改變?

1

我終於想出:

予設定值[2]對WeakReference到對象,而不是將其設置爲對象的副本。
然後,我只需要得到WeakReference的價值,並有我的對象...

相關問題