2

クラスのプロパティを参照したい一連の「コード」があります。ただし、辞書の値を設定すると、プロパティは更新されません。以下の例

public Foo() {
    this.CodeMap = new Dictionary<string, object>();
    this.CodeMap.Add("stat", this.Status);
    this.CodeMap.Add("ver", this.Version);
}

public int Status { get; set; }

public int Version { get; set; }

そして呼び出しコード

foo.CodeMap["stat"] = 27;
/* foo.Status is not set to 27 */

.NET でこれを行う方法はありますか。辞書の値が参照値ではないためにエラーが発生すると思いますが、これを行う最善の方法はわかりません。https://stackoverflow.com/a/10350484/450745を見ましたが、それは私が望むものの反対です。

4

5 に答える 5

3

将来のビューアーには、単純なケースでは Func'<'T'>' を使用するだけで十分です。

  public string TestProperty {get; set;}
  public Dictionary<int, Func<string>> dictionary;

  Constructor()
  {
    dictionary = new Dictionary<int, Func<string>>
    {
        {1, ()=>TestProperty }
    }
  }

そして、次のように使用する場合:

  dictionary[1]() or dictionary[1].Invoke()

現時点でのプロパティの実際の値を返します。

于 2015-07-02T12:41:41.590 に答える
1

辞書の値が参照値ではないため、エラーが発生すると思いますが、

いいえ、設定していないためですfoo.Statusfoo.CodeMapfoo.Statusは異なります。

値を同期する場合は、手動で行う必要があります。メソッドを継承しIDictionary<TKey,TValue>てオーバーライドできますAdd

お気に入り

void Add(TKey key, TValue value)
{
   if (key is string && key.Equals("stat"))
   {
      this.stat = (int)value;
   }
}
于 2013-01-12T04:25:41.020 に答える
1

Dictionary割り当てが行われたときにステータスの値に関係なく、キー「stat」を追加するため、コードは機能しません。後でそのキーの値を更新しても、プロパティは自動的に更新されません。ある時点でのプロパティの値を に追加していますがDictionary、プロパティ自体は追加していません。

あなたがやりたいことは、標準では不可能ですDictionary。ただし、ひどいとは思われないオプションがいくつかあります。

オブザーバブル ディクショナリ

このブログ投稿とこのスタックオーバーフロー スレッドを参照してください。

IDictionary<TKey, TValue>一般的な考え方は、 、INotifyCollectionChanged、およびを継承するクラスを作成することINotifyPropertyChangedです。

これにより、理論的にはいくつかのプロパティやその他のやりたいことを更新できるイベントハンドラーを作成できるいくつかのフックが得られます。

コードをリファクタリングする

上記が気に入らない場合は、コードを少しリファクタリングできます。

このことを考慮:

public class Foo
{
    public Dictionary<string, object> CodeMap;

    public int Status
    {
        get 
        {
            int status;
            if (int.TryParse(CodeMap["stat"].ToString(), out status))
            {
                return status;
            }
            else
            {
                throw new Exception("Status has a non-numeric value");
            }
        }
        set 
        { 
            CodeMap["stat"] = value; 
        }
    }

    public Foo()
    {
        CodeMap = new Dictionary<string, object>();
    }
}

次に、同じ呼び出しを行うことができます。

Foo foo = new Foo();
foo.CodeMap["stat"] = 27;

Console.WriteLine(foo.Status.ToString());  // prints 27

うまくいけば、これが機能する理由はかなり明白です。これで、プロパティは実際に を参照しDictionaryます。KeyNotFoundExceptionゲッターがそのキーにアクセスしようとしたときに取得するため、以前と同じ方法で初期値を追加できないことに注意してください。ただし、これはかなり小さな欠点だと思います。

于 2013-01-12T05:11:12.110 に答える
0

もう1つの方法は、ExpandoObjectを使用することです。これは、辞書に一方向にバインドするサンプルです。

public class Foo
{
    public Foo()
    {
        Properties = new ExpandoObject();
        Status = 0;
        Version = 0;
    }

    public dynamic Properties { get; set; }

    public IDictionary<string, object> CodeMap
    {
        get { return Properties; }
    }

    private int _status;
    public int Status
    {
        get { return _status; }
        set
        {
            _status = value;
            Properties.stat = _status;
        }
    }

    private int _version;
    public int Version
    {
        get { return _version; }
        set
        {
            _version = value;
            Properties.ver = _version;
        }
    }
}

使用:

var foo = new Foo
                {
                    Status = 1,
                    Version = 2
                };

Console.WriteLine(foo.CodeMap["stat"]);
Console.WriteLine(foo.CodeMap["ver"]);
Console.WriteLine(foo.Properties.stat);
Console.WriteLine(foo.Properties.ver);
于 2013-01-12T13:30:18.990 に答える
0

ディクショナリは、前の値プロパティの値を更新しません。foo.CodeMap["stat"] = 27;の以前の値foo.CodeMap["stat"]( の値)を保存すると、 でStatus上書きされ27ます。

ディクショナリ内のキー (この場合は「stat」) で識別される位置はデータ ストアです。つまり、データCodeMap["stat"]の保存場所であり、その逆ではありません。この場所に保存すると、以前のデータが上書きされます。

解決しようとしている実際の問題について詳しく説明する必要があります。あなたの質問は、読者が実際の必要性/問題を推測するのに十分明確ではありません。

于 2013-01-12T04:38:22.910 に答える