为什么 IntelliSense 认为我字典中的值是动态的?

Why does IntelliSense think a value from my dictionary is a dynamic?

假设我有以下方法:

private void something()
{
    string text = "This is obviously a string";
    dynamic pietje = Guid.NewGuid();

    var dict = new Dictionary<Guid, string>();
    dict.Add(pietje, text);

    var someText = dict[pietje];
}

下图显示 IntelliSense 仍然认为它是动态的,尽管我看不出这可能是字符串(或空值)以外的任何东西

我是否遗漏了一个设置,或者是否有什么东西阻止 IntelliSense 知道 someText 应该是一个字符串?我可能过于依赖 IntelliSense,但对于某些对象来说,手动键入整个方法或 属性 正确命名会变得相当困难。

那么这是什么原因呢?我能做些什么来解决这个问题吗?

显然我可以通过多种方式修复它:

string someText = dict[pietje];
var someText = dict[(Guid)pietje];
var someText = dict[pietje] as string;

等 但这不是重点,也不是我想要的。

因为pietjedynamicvar someText = dict[pietje];的执行结果是运行时决定的。在那之前,该调用的正确性和结果是未知的,因此 dynamic.

我猜你是想在这里使用 var,因为你事先知道 pietje 的类型。


正如评论中所说:您遵循 所有动态评估都在运行时完成的简单规则。您可以输入一个无效的字段名称并让它继续编译。

这个问题在很多情况下都会出现。 SO中的经典问题:

public string Foo(string fooable) { .... }

dynamic fooable = "whatever";
var whyAmIDynamic = Foo(fooable);

嗯?为什么是 wyAmIDynamic dynamic?!?编译器应该知道 wyAmIDynamicstring,不是吗?

是的,但后来有人出现并写下了以下内容:

public int Foo(int fooable) { .... } //a new overload of Foo

而现在,Foo(fooable) return 应该怎么办? dynamic 似乎是唯一合理的选择;涉及 dynamic 参数的方法调用在运行时才能解析。

在您的特定情况下,编译器没有理由不相信有人可能会出现并对 Dictionary<TKey, TValue> 实施以下荒谬的重载:

public int this[string key] { ... }

这个重载有意义吗?不。编译器的工作是弄清楚它是否有意义吗?不,它 合法 吗?是的,因此索引器 return 是一个 dynamic 变量。

您正在指定 Dictionary<Guid, string> 类型的词典。当您尝试阅读时,您正在使用 dynamic 作为字典的关键字,甚至不知道这是否是一个有效的语句。

有一种相对简单的方法可以解决此问题:

查找字典中与声明相同类型的key

string text = "This is obviously a string";
dynamic pietje = Guid.NewGuid();

var dict = new Dictionary<Guid, string>();
dict.Add(pietje, text);

var someText = dict[(Guid)pietje];
//Of course you could go about casting this in numerous ways