Why does the Linq Cast<> helper not work with the implicit cast operator?

ⅰ亾dé卋堺 提交于 2019-11-27 21:22:55

The short answer would be simply: the Cast<T> method doesn't support custom conversion operators.

In the first example:

B b = a;
B b2 = (B)a;

the compiler can see this B(A a) operator during static analysis; the compiler interprets this as a static call to your custom operator method. In the second example:

foreach (object obj in source) 
    yield return (T)obj; 

that has no knowledge of the operator; this is implemented via unbox.any (which is the same as castclass if T is a ref-type).

There is also a third option: if you went via dynamic, the runtime implementation tries to mimic compiler rules, so this will find the operator ... but not as part of the C#-to-IL compile step:

dynamic b = a; // note that `dynamic` here is *almost* the same as `object`
B b2 = b;

So why my explicit cast work, and the one inside .Cast<> doesn't?

Your explicit cast knows at compile time what the source and destination types are. The compiler can spot the explicit conversion, and emit code to invoke it.

That isn't the case with generic types. Note that this isn't specific to Cast or LINQ in general - you'd see the same thing if you tried a simple Convert method:

public static TTarget Convert<TSource, TTarget>(TSource value)
{
    return (TTarget) value;
}

That will not invoke any user-defined conversions - or even conversions from (say) int to long. It will only perform reference conversions and boxing/unboxing conversions. It's just part of how generics work.

Enumerable.Cast<T> is a .Net framework method and has a behavior that makes sense in all of the .Net languages that call it.

See also, Ander Hejlsberg's reply on this discussion.


Does the compiler sugar-up my explicit cast ?

What you call an "implicit cast operator" is actually an "implicit conversion operator". It's a common mistake.

C# allows you to specify conversions using the casting syntax. When this happens, you are using a different instance (converting), not changing the reference to the same instance (casting).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!