Convert to IEnumerable?

2019-03-25 12:21发布

I wrote this extension method :

public static class A
{
 public static IEnumerable<dynamic> AsDynamic<T>(this IEnumerable<T> f)
    {
        foreach (var element in f)
        {
                yield return (dynamic) element;
        }   
    }
}

And tested it :

List<int> l   = new List<int>(){1,2,3};
Console.WriteLine ( l.AsDynamic().GetType());

However the output is : typeof (IEnumerable<Object>)

  • Why it is not typeof (IEnumerable<dynamic>) ?

  • How can I make it to be like it ?

4条回答
虎瘦雄心在
2楼-- · 2019-03-25 12:48

Because dynamic is not a type

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

dynamic just resolves the actual type at runtime

查看更多
Fickle 薄情
3楼-- · 2019-03-25 12:51

I think that you have a misunderstanding of what dynamic means. Essentially, when you tell the compiler that an object's type is dynamic, you "promise" that the object at runtime will support whatever methods or properties that you invoke, in exchange for the compiler not complaining at compile time. You also promise that you will face the consequences if you break your promise.

When you say that an object is dynamic, the compiler cannot make assumptions about the type, so it uses object, knowing that anything can be stored as object. When you make an IEnumerable<dynamic>, it becomes IEnumerable<object>, with one significant difference: you can call any method on its elements, and the compiler will not say a word:

IEnumerable<SomeType> original = ...
foreach (dynamic x in original.AsDynamic()) { // Using your method
    Console.WriteLine(x.SomeUnsupportedMethod()); // The compiler is silent!
}

Since original.AsDynamic() gives a sequence of dynamic objects, the compiler does not complain about your call to SomeUnsupportedMethod. If the method is indeed not supported at runtime, the program will crash; if the method is actually supported by elements of SomeType, there would be no crash, and the method will be invoked.

That's all the dynamic will do for you; statically, the "placeholder" will remain object, and typeof will tell you as much. But the exact capabilities of the object (its methods and properties) will not be examined until runtime.

查看更多
该账号已被封号
4楼-- · 2019-03-25 13:00

Try the Linq Extension method Cast(). But I'm not sure it will work with dynamic.

查看更多
姐就是有狂的资本
5楼-- · 2019-03-25 13:07

By design, runtime bindings behave as similarly as possible to static binding.

So the runtime type would betypeof (IEnumerable<Object>)

The static type would be typeof (IEnumerable<dynamic>)

Also

The runtime treats this true conceptually

typeof(object)==typeof(dynamic)

So,

A dynamic type is like object except it lets you use in ways that aren't known at compile time.

查看更多
登录 后发表回答