这是因为Dictionary<TKey, TValue> 实现了IDictionary<TKey, TValue> 的通用版本和非通用版本(只是IDictionary 产生Object)。
查看源码可以很容易看到indexer of the generic version在找不到key时显式抛出:
public TValue this[TKey key]
{
get
{
int i = FindEntry(key);
if (i >= 0) return entries[i].value;
ThrowHelper.ThrowKeyNotFoundException(); // <-- this line
return default(TValue);
}
}
但是non-generic version 没有:
object IDictionary.this[object key]
{
get
{
if (IsCompatibleKey(key))
{
int i = FindEntry((TKey)key);
if (i >= 0)
return entries[i].value;
}
return null;
}
}
然后,除非您将 Dictionary 显式转换为非通用版本,否则您将调用在找不到键时抛出的索引器。
更新(根据您的评论):
由于IDictionary(非泛型版本)是在.NET 1.0 中引入的(当时还不支持泛型),它使用和返回的唯一类型显然是System.Object(可以测试@987654332 @)。
因此,在找不到密钥时不要扔是有意义的,因为可以简单地这样做:
dict["nonExistingKey"] != null
但是,一旦引入了通用 IDictionary<TKey, TValue>,TValue 也可以设置为值类型(如 int 或 DateTime),并且必须将上述模式调整为:
var dict = new Dictionary<string, int>();
dict["nonExistingKey"] != 0;
dict["nonExistingKey"] != default(int);
哪个不太流畅,不太标准,使用起来更麻烦。
从“设计角度”来看,我认为他们决定保留 IDictionary 的向后兼容性,同时主动抛出通用版本。