C# 10 推断的委托类型是否涉及隐式转换?

Do C# 10 inferred delegate types involve an implicit conversion?

提问人:Maxime Vey 提问时间:9/3/2023 最后编辑:Maxime Vey 更新时间:9/10/2023 访问量:92

问:

C# 10 以来,引入了推断的委托类型

但是,我对该功能的行为感到非常困惑:

一般来说,我认为我们可以合理地预期,如果这可以编译:

var x = (my_expression); // inferred type
SomeType y = x;

此单个赋值也应编译:

SomeType y = (my_expression);

但是,当涉及推断的委托类型时,这并不满足:

using System;

class Program {

    class FunctionWrapper<Output> {
        private Func<Output> WrappedFunction { get; }
        public FunctionWrapper(Func<Output> function) => WrappedFunction = function;
        public static implicit operator FunctionWrapper<Output>(Func<Output> function) => new FunctionWrapper<Output>(function);
    }

    public delegate void DoStuffDelegate<Inout>(ref Inout Input);

    static void Main(string[] args) {

        var funcLambda = () => "hello"; // type is inferred here...
        FunctionWrapper<string> funcWrapper = funcLambda;  // ... it compiles
        // but if we do a single assignment...
        FunctionWrapper<string> funcWrapper2 = () => "hello"; // CS1660 - this does not compile anymore... Why?

        // the exact opposite happens with delegates:

        // if we do a single assignment...
        DoStuffDelegate<string> delegWrapper2 = (ref string input) => { input = input + input; }; // ... it compiles
        // but if type is inferred...
        var delegateLambda = (ref string input) => { input = input + input; }; // type is inferred
        DoStuffDelegate<string> delegWrapper1 = delegateLambda; // CS0029 - this does not compile anymore...        
    }
}

我的印象是,推断的委托类型意味着在某个阶段的隐式转换,但情况可能并非如此。

(代码链接:https://godbolt.org/z/3sbd9ndrT)

我尝试了不同的编译器,并搜索了有关推断委托类型行为的文档、讨论和潜在的已知问题,但没有成功。

有人可以告诉这是语言/编译器缺陷,还是我对这些转换的期望不合理?

先谢谢你。

lambda 隐式转换 net-7.0 c#-10.0 推断类型

评论

0赞 Maxime Vey 9/10/2023
我在 csharplang github 上问了我的问题,得到了几个详细而全面的答案: github.com/dotnet/csharplang/discussions/7514

答:

0赞 Paulo Morgado 9/3/2023 #1

看起来像是IDE0004的问题。

您应该报告此问题

评论

0赞 Maxime Vey 9/4/2023
我同意IDE0004是错误的,因为它与编译器行为不一致。但是,我仍然在这里质疑语言和编译器行为。如果 “var x = expr;SomeType y = x;“ 编译,直接执行 ”SomeType y = expr;“ 也应该编译,对吧?
0赞 Paulo Morgado 9/5/2023
IDE0004不是编译器错误。您可以尝试 sharplab.io 无法获得 IDEXXXX 诊断或命令行编译的地方。
0赞 Maxime Vey 9/5/2023
是的,我知道IDE0004不是编译器错误。IDE0004不是最初问题的主要主题,如果我不清楚,对不起。您可以忽略提及IDE0004。问题确实是关于编译错误。
0赞 Paulo Morgado 9/5/2023
您遇到了哪些编译错误?
0赞 Maxime Vey 9/5/2023
我提供的代码片段中包含的所有代码 - 如果您启用了被注释掉的代码,您也应该获得它们。