为什么 Linq Cast<>助手不能与隐式转换运算符一起使用? [英] Why does the Linq Cast<> helper not work with the implicit cast operator?
问题描述
在决定重复投票之前,请阅读到最后...
我有一个类型将 implicit cast
运算符实现为另一种类型:
I have a type that implements an implicit cast
operator to another type:
class A
{
private B b;
public static implicit operator B(A a) { return a.b; }
}
class B
{
}
现在,隐式和显式转换工作得很好:
Now, implicit and explicit casting work just fine:
B b = a;
B b2 = (B)a;
...那么为什么 Linq 的 .Cast<>
没有?
...so how come Linq's .Cast<>
doesn't?
A[] aa = new A[]{...};
var bb = aa.Cast<B>(); //throws InvalidCastException
查看 .Cast<>
的源代码,没有什么神奇之处:如果参数确实是 IEnumerable
的一些特殊情况,然后:
Looking at the source code for .Cast<>
, there's not much magic going on: a few special cases if the parameter really is a IEnumerable<B>
, and then:
foreach (object obj in source)
yield return (T)obj;
// ^^ this looks quite similar to the above B b2 = (B)a;
那么为什么 my 显式转换有效,而 .Cast<>
中的转换无效?
So why does my explicit cast work, but not the one inside .Cast<>
?
编译器是否对我的显式转换进行了修饰?
Does the compiler sugar-up my explicit cast ?
附注.我看到了这个问题,但我认为它的答案并不能真正解释正在发生的事情.
PS. I saw this question but I don't think its answers really explain what's going on.
推荐答案
简短的回答很简单:Cast
方法不支持自定义转换运算符.
The short answer would be simply: the Cast<T>
method doesn't support custom conversion operators.
在第一个例子中:
B b = a;
B b2 = (B)a;
编译器在静态分析时可以看到这个B(A a)
操作符;编译器将此解释为对自定义运算符方法的静态 call
.在第二个例子中:
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;
不知道操作符;这是通过 unbox.any
实现的(如果 T
是引用类型,则与 castclass
相同).
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).
还有第三种选择:如果你通过dynamic
,运行时实现会尝试模仿编译器规则,所以这会找到运算符......但不会作为 C# 到 IL 编译步骤的一部分:
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;
这篇关于为什么 Linq Cast<>助手不能与隐式转换运算符一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!