为什么 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;
等
但这不是重点,也不是我想要的。
因为pietje
是dynamic
,var someText = dict[pietje];
的执行结果是运行时决定的。在那之前,该调用的正确性和结果是未知的,因此 dynamic
.
我猜你是想在这里使用 var
,因为你事先知道 pietje
的类型。
正如评论中所说:您遵循 所有动态评估都在运行时完成的简单规则。您可以输入一个无效的字段名称并让它继续编译。
这个问题在很多情况下都会出现。 SO中的经典问题:
public string Foo(string fooable) { .... }
dynamic fooable = "whatever";
var whyAmIDynamic = Foo(fooable);
嗯?为什么是 wyAmIDynamic
dynamic
?!?编译器应该知道 wyAmIDynamic
是 string
,不是吗?
是的,但后来有人出现并写下了以下内容:
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
假设我有以下方法:
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;
等 但这不是重点,也不是我想要的。
因为pietje
是dynamic
,var someText = dict[pietje];
的执行结果是运行时决定的。在那之前,该调用的正确性和结果是未知的,因此 dynamic
.
我猜你是想在这里使用 var
,因为你事先知道 pietje
的类型。
正如评论中所说:您遵循 所有动态评估都在运行时完成的简单规则。您可以输入一个无效的字段名称并让它继续编译。
这个问题在很多情况下都会出现。 SO中的经典问题:
public string Foo(string fooable) { .... }
dynamic fooable = "whatever";
var whyAmIDynamic = Foo(fooable);
嗯?为什么是 wyAmIDynamic
dynamic
?!?编译器应该知道 wyAmIDynamic
是 string
,不是吗?
是的,但后来有人出现并写下了以下内容:
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