我写了这个扩展方法:
public static class A
{
public static IEnumerable<dynamic> AsDynamic<T>(this IEnumerable<T> f)
{
foreach (var element in f)
{
yield return (dynamic) element;
}
}
}
并测试了它:
List<int> l = new List<int>(){1,2,3};
Console.WriteLine ( l.AsDynamic().GetType());
但输出为:typeof (IEnumerable<Object>)
为什么不是typeof (IEnumerable<dynamic>)
?
我怎样才能让它像它一样?
答案 0 :(得分:21)
我认为你对dynamic
的含义有误解。本质上,当您告诉编译器对象的类型是dynamic
时,您“保证”对象在运行时将支持您调用的任何方法或属性,以换取编译器而不是在编译时抱怨 。如果你违背诺言,你也承诺会面临后果。
当你说对象是dynamic
时,编译器不能对类型做出假设,所以它使用object
,知道任何东西都可以存储为object
。当你创建IEnumerable<dynamic>
时,它变为IEnumerable<object>
,但有一个显着的区别:你可以在其元素上调用任何方法,编译器不会说一个字:
IEnumerable<SomeType> original = ...
foreach (dynamic x in original.AsDynamic()) { // Using your method
Console.WriteLine(x.SomeUnsupportedMethod()); // The compiler is silent!
}
由于original.AsDynamic()
提供了一系列dynamic
个对象,因此编译器不会抱怨您对SomeUnsupportedMethod
的调用。如果在运行时确实不支持该方法,程序将崩溃;如果SomeType
的元素实际支持该方法,则不会发生崩溃,并且将调用该方法。
所有dynamic
都会为你做的;静态地,“占位符”将保持object
,typeof
将告诉您。但是直到运行时才会检查对象的确切功能(其方法和属性)。
答案 1 :(得分:1)
按照设计,运行时绑定的行为与静态绑定的类似。
因此运行时类型为typeof (IEnumerable<Object>)
静态类型为typeof (IEnumerable<dynamic>)
另外
运行时从概念上理解这个
typeof(object)==typeof(dynamic)
所以,
动态类型就像对象,但它允许您以编译时未知的方式使用。
答案 2 :(得分:0)
尝试使用Linq扩展方法Cast()。但我不确定它是否适用于动态。
答案 3 :(得分:0)
因为dynamic
不是类型
Console.WriteLine(typeof(dynamic)); // error
dynamic只是在运行时解析实际类型