0


私は現在VariableWatcher、C# のクラスに取り組んでいます。
私がやりたいことは、変数が特定の値に変更されるたびにイベントを発生させることです。
例: 私は を持っていますがbool a、これは false です。これを、イベントを発生させる値とともに VariableWatcher クラスに渡しますtrue
私はすでにこの問題の解決策に取り組みましたが、ボクシング/アンボクシングについて明らかに誤解していました。

これは私のコードです:

  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);
    }
}

私の質問は: Value[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
}
4

2 に答える 2

1

私はついにそれを理解しました:

Value[2] をWeakReferenceオブジェクトのコピーに設定するのではなく、オブジェクトに設定します。
次に、WeakReference から値を取得するだけで、オブジェクトがあります...

于 2011-04-17T15:38:21.733 に答える
1

それは正しい。トリガーされることはありません。貴重な型をボックス化するときは、実際に値のコピーを作成してメモリに入れます。したがって、変数の値を変更する場合、ボックス化された値は変更されません。最初に頭に浮かぶのは、安全でないコンテキストを使用して変数アドレスをボックス化することですが、残念ながら.NETはポインターのボックス化をサポートしていません( MSDNから):

ポインター型はオブジェクトから継承されず、ポインター型とオブジェクトの間に変換は存在しません。また、ボックス化とボックス化解除はポインタをサポートしていません。ただし、異なるポインター型の間、およびポインター型と整数型の間で変換することはできます。

したがって、唯一可能な方法は、安全でないコンテキストを使用し、すべての変数のアドレス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());
        }

しかし、コメントで述べたように、プロパティが変更されたときにトリガーされるイベントを実装してみませんか?

于 2011-04-17T14:02:08.123 に答える