说我有以下方法:
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仍然认为它是动态的,即使我没有看到这可能是一个字符串以外的任何东西(或null)
我是否错过了某个设置,或者有什么东西阻止IntelliSense知道someText
应该是一个字符串?我可能会过度依赖IntelliSense,但某些对象很难正确地手动输入整个方法或属性名称。
那么这是什么原因?我有什么办法可以解决这个问题吗?
显然我可以通过多种方式解决它:
string someText = dict[pietje];
var someText = dict[(Guid)pietje];
var someText = dict[pietje] as string;
等。 但这不是重点,也不是我想要的。
答案 0 :(得分:6)
在许多情况下,这个问题都会出现。 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)
应该返回什么? dynamic
似乎是唯一合理的选择;涉及dynamic
参数的方法调用无法在运行时解析。
在您的具体情况下,编译器没有理由不相信某人可能会出现并对Dictionary<TKey, TValue>
执行以下荒谬的重载:
public int this[string key] { ... }
这种过载是否有意义?是否编译器业务是否有意义?不,这是合法吗?是的,因此索引器返回dynamic
变量。
答案 1 :(得分:3)
因为pietje
是dynamic
,所以var someText = dict[pietje];
的执行结果是在运行时确定的。在此之前,该呼叫的正确性和结果是未知的,因此dynamic
。
我想你的意思是在这里使用var
,因为你事先知道pietje
的类型。
如评论中所述:您遵循所有动态评估在运行时完成的简单规则。您可以键入无效的字段名称,但仍然可以编译。
答案 2 :(得分:0)
您要将词典指定为Dictionary<Guid, string>
类型。当你尝试阅读时,你使用dynamic
作为字典的关键,甚至不知道这是否是一个有效的陈述。
解决此问题有一种相对简单的方法:
使用与声明
相同的类型对字典中的键进行寻址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