2016-06-21 8 views
0

は、次のコードを考えてみましょう:ConcurrentDictionaryを使用するときに値としてnullを追加できないのはなぜですか?

// holds the actual values 
     private volatile ConcurrentDictionary<string, Object> values; 

     public object this[string key] { 
      get {  
       // exception is thrown on this line   
       return values.GetOrAdd(key, null);     
      } 
      set { 
       values.AddOrUpdate(key, value, (k, v) => value);     
      } 
     } 

それはまだ存在しない場合は私がやりたいことは、単に辞書にエントリを作成しています。何か明示的に設定するまでは価値はないはずです。しかし、この例外が発生します。

An unhandled exception of type 'System.ArgumentNullException' occurred in mscorlib.dll 

Additional information: Value cannot be null. 

ドキュメントには、キーはnullにすることはできません。意味があります。しかし、なぜ私は値のためのこの例外を得ていますか?この方法を理解していないのですか?

+1

@sstan "追加情報:**バリュー**をnullにすることはできません。 –

+0

@sstanそれはOPが書いたものです。 –

+0

ディクショナリの目的はすべて、値をルックアップするためにキーを使用できるようにすることであるため、NULL値を許可することは意味がありません。キーに値がない場合、辞書には属しません。IRLのように、単語が定義されるまで辞書には属しません。あなたは辞書に未定義の言葉を見つけませんか? –

答えて

4

コードは、Funcを引数とするもう1つのGetOrAddを呼び出して終了します(また、nullにする必要がないことを明示的に要求 - 「keyまたはvalueFactoryがnullです」)。

public TValue GetOrAdd(TKey key,Func<TKey, TValue> valueFactory)... 

修正:指定明示的に入力します。

values.GetOrAdd("test", (Object)null); 

理由:C#が常により具体的な一致を見つけようとするとFunc<TKey, TValue>Objectより具体的である - ので、オーバーライドが選択されます。

+2

OPが "TValue"のより具体的な型を使用していた場合、コンパイラは彼に "call is ambiguous"というエラーメッセージを表示して助けてくれたでしょう。 – sstan

+0

ありがとう!これは非常に意味があります。 Objectへのキャストは、私の直ぐ問題を軽減します。 – dmarra

関連する問題