Func <MyType>隐式转换为MyType

Dan*_*ugg 9 c# callback implicit-conversion

鉴于以下课程:

public class MyType
{
    public static implicit operator MyType(Func<MyType> wrapper) {
        return wrapper();
    }
}
Run Code Online (Sandbox Code Playgroud)

从隐式演员Func<MyType>MyType,我假设以下是可能的:

public MyType MyTypeWrapper() {
    return new MyType();
}

public void MyTestMethod() {
    MyType m = MyTypeWrapper; // not a call!
}
Run Code Online (Sandbox Code Playgroud)

但是我得到了:

无法将方法组"MyTypeWrapper"转换为非委托类型"Test.MyType".你打算调用这个方法吗?

其中,不幸的是对我,对搜索时(如我预期的一半),导致 问题,这个问题的答案是:

嘿,你打瞌睡; 折腾()结束了WhateverMethod!

现在,当我输入这个时,我注意到显式转换实际上是编译的:

MyType m = (MyType) MyTypeWrapper;
Run Code Online (Sandbox Code Playgroud)

为什么我不能隐式转换一个Func<MyType>MyType为我所描述?

Eri*_*ert 12

这很不幸.我很确定你发现了编译器错误,而且规范的这一部分非常难以阅读.

C#4规范的第6.4.4节解释了为什么隐式转换是非法的.

算法是这样的.首先看一下源类型和目标类型.没有源类型,因为方法组没有类型.目标类型是MyType.因此,搜索MyType用户定义的隐式转换.现在的问题是:什么是适用的用户定义的运算符集...从包含S的类型转换S是源类型,我们已经确定没有源类型.所以这已经证明转换失败了.但是,即使编译出于某种原因决定了你的Func<MyType>转换是适用的,规则是一个标准的隐式转换...进行.方法组转换有意不归类为标准转换.

所以这就是为什么它应该是非法的.

为什么显性演员合法?

没有理由这样做.这似乎是一个错误.

这很不幸; 许多道歉的错误.我会把它报告给我以前的同事; 如果他们的分析与我的相冲突,我会更新答案.

更新:我以前的同事告诉我,源表达式假定具有类型的规范问题将通过规范的下一版本中的重新措辞来解决.还没有关于显式演员行为是否是一个错误的消息.

  • 如果编译器设计方面的专家在阅读规范时遇到困难,那么对于我们这些凡人来说,没有太多希望. (4认同)
  • @SLaks:编译器知道在隐式情况下查看`MyType`,因为它知道这是隐式转换的唯一可能的目标类型.与这种情况形成对比:如果您有一个*显式*用户定义的从Giraffe到Fruit的转换,并且您明确地将一个对Animal的引用转换为类型Banana,那么编译器将搜索Animal,Banana和Fruit用于转换运算符但不搜索Giraffe,所以如果在Giraffe上声明用户定义的转换,那你就不走运了. (2认同)

SLa*_*aks 11

您已经在使用从方法组到内置的隐式转换Func<MyType>.

编译器不会一次执行两次隐式转换.

一旦对类进行了显式转换,编译器就会知道对任何可以显式转换为类的类型进行隐式转换.

  • 只是为了澄清:编译器*将*链接一些隐式转换.例如,如果您有一个用户定义的从int到Frob的隐式转换,那么您可以从short获得免费转换.短 - > int - > Frob.允许的转换记录在规范的第6.3节中,方法组转换故意不在该列表中. (2认同)