动态List的意外行为

时间:2014-10-15 15:31:25

标签: c# generics dynamic

以下内容在最后一行引发运行时异常:

dynamic dynamicCollection = new List<ExpandoObject>();

dynamic itemOne = new ExpandoObject();
itemOne.Name = "itemOne";
dynamicCollection.Add(itemOne);

dynamic itemTwo = new ExpandoObject();
itemTwo.Name = "itemTwo";
dynamicCollection.Add(itemTwo);

var firstItem = dynamicCollection.First();

&#39;&System.Collections.Generic.List LT; System.Dynamic.ExpandoObject&GT;&#39;不包含&#39; First&#39;

的定义

这里发生了什么?这看起来完全合法。它显然被识别为List<ExpandoObject>,而通用集合不应该关注T的价值..对吗?

2 个答案:

答案 0 :(得分:4)

First()方法是位于System.Linq.Enumerable而不是System.Collections.Generic.List<T>的{​​{3}}。这意味着在运行时查找成员dyanmic对象无法解析.First()的含义,因为List<T>如上所述,不包含该方法。这里最大的问题是它正在寻找一个成员,并且在解决时不会检查扩展方法。

从句法上讲,你可以说List<T>.First()因为它的语法糖。您还可以参考完整方法,并且必须使此代码生效,因为dynamic对象不会检查扩展方法。

Enumerable.First(dyanmicCollection);

在编译时,这就是扩展方法无论如何有效扩展,所以你基本上绕过了糖,

答案 1 :(得分:1)

您真的需要dynamicCollection成为dynamic吗?如果没有,您可以使用具体类型作为列表本身:

var dynamicCollection = new List<ExpandoObject>();
...
dynamic firstItem = dynamicCollection.First();
Console.WriteLine(firstItem.Name);

然后dynamicCollection.First()将被解析为您期望的扩展方法调用。 此方法的返回类型为ExpandoObject,因此您还应将其转换为dynamic以访问Name属性。