【问题标题】:Why can I not add null as a value when using ConcurrentDictionary?为什么在使用 ConcurrentDictionary 时不能将 null 添加为值?
【发布时间】:2016-06-21 17:38:01
【问题描述】:

考虑以下代码:

// 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.

文档声明 key 不能为 null,这是有道理的。为什么我得到这个例外的价值呢?我不理解这种方法吗?

【问题讨论】:

  • @sstan "附加信息:不能为空。"
  • @sstan 这就是 OP 写的。
  • 由于字典的全部目的是允许使用键来查找值,因此允许空值是没有意义的。如果键没有值,则它不属于字典,就像 IRL 一个单词在它有定义之前不属于字典。您不会在字典中找到未定义的单词,对吗?
  • @KenWhite null 完全允许作为字典值。请参阅 Alexei 的回答。
  • @piedar:我并不是说它不被严格允许。我的意思是我所说的;允许它是没有意义的,因为根据定义,一个有键但没有值的字典是无用的。

标签: c# concurrentdictionary


【解决方案1】:

代码最终调用了另一个GetOrAdd,它将Func 作为参数(它明确要求不为空 - “key or valueFactory 为空。”)。

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

修复:明确指定类型:

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

为什么:C# 总是尝试找到更具体的匹配项,而 Func&lt;TKey, TValue&gt;Object 更具体 - 因此选择了覆盖。

【讨论】:

  • 如果 OP 为 TValue 使用了更具体的类型,编译器会通过给他“调用不明确”错误消息来帮助他。
  • 谢谢!这很有意义。转换为 Object 缓解了我的直接问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多