动态变量不接受没有类型转换的继承属性

时间:2015-01-20 16:13:15

标签: c#

我有这个动态变量来序列化json字符串。

dynamic result = serializer.Deserialize<dynamic>(json);

从此我得到result["success"],它在运行时解析为Dictionary<string, object>。然后,我应用了名称空间System.Linq,以便我可以在变量上调用.First() 我写了

KeyValuePair<string, object> temp = result["success"].First();

然后我收到错误,

  

'System.Collections.Generic.Dictionary'不包含'First'的定义

(但它确实,LINQ,对吗?)现在我改变了这样的代码。

KeyValuePair<string, object> temp = 
    ((Dictionary<string, object>)result["success"]).First();

它没有任何故障。所以我认为可能是因为动态解析变量。然后我尝试使用Dictionary<TKey, TValue>这样的本地属性

var foo = result["success"].Keys;

这也没有任何故障,它让我困惑,因此这篇文章。

我所理解的是,动态解析的变量只接受本机属性,需要对继承的属性进行类型转换

我怀疑是

  1. 我的理解是否正确?
  2. 这是预期的行为吗?
  3. 若然,为何如此?
  4. P.S:用C#4.0编码

2 个答案:

答案 0 :(得分:5)

  

但是,对LINQ来说,确实如此吗?

不,它没有。在IEnumerable<T>的{​​{1}}上有扩展方法,但无法以“正常”方式在First()值上调用扩展方法。

但是,您可以将其用作常规静态方法:

dynamic

当你施放 KeyValuePair<string, object> temp = Enumerable.First(result["success"]); 时,那仍然是动态绑定的 - 在演员之后,所有内容都只是静态输入。

答案 1 :(得分:1)

这是因为扩展方法语法糖。当你在这样的字典上调用First时:

dictionary.First();

编译器将其转换为:

Enumerable.First(dictionary);

但是在这种情况下,因为类型是dynamic,编译器对First一无所知。或者换句话说,它不会检查是否存在名为{{1}的扩展方法并尝试将代码转换为普通的方法调用。在运行时,它会查找实例方法。并且因为类型没有任何名为First的实例方法,所以会得到异常。要解决此问题,您只需将您的方法称为正常而非扩展,就像Jon Skeet的回答中所述。