10

我写了这个扩展方法:

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>)

  • 我怎样才能让它像它一样?

4

4 回答 4

27

我认为你对什么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会告诉你很多。但是直到运行时才会检查对象的确切功能(它的方法和属性)。

于 2013-01-01T14:17:14.843 回答
1

因为dynamic不是类型

Console.WriteLine(typeof(dynamic)); // error

动态只是在运行时解析实际类型

于 2013-01-01T14:04:18.627 回答
1

按照设计,运行时绑定的行为与静态绑定尽可能相似

所以运行时类型将是typeof (IEnumerable<Object>)

静态类型是typeof (IEnumerable<dynamic>)

运行时在概念上将此视为 true

typeof(object)==typeof(dynamic)

所以,

动态类型类似于对象,只是它允许您以编译时未知的方式使用。

于 2013-01-01T14:08:02.350 回答
0

尝试 Linq 扩展方法Cast()。但我不确定它是否适用于动态。

于 2013-01-01T14:04:07.023 回答