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

问题描述 投票:0回答:1

推断委托类型C# 10开始引入。

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

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

var x = (my_expression);
SomeType y = x;

这也应该编译:

SomeType y = (my_expression);

但是,当涉及推断的委托类型时,这就不能满足。

我的印象是推断的委托类型意味着在某个阶段的隐式转换,但事实可能不应该如此。

[我的 IDE (Visual Studio 2022) 甚至错误地报告 IDE0004(冗余转换)。 如果我删除强制转换,编译实际上会失败...]

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 class ActionWrapper<Input> {
        private Action<Input> WrappedAction { get; }
        public ActionWrapper(Action<Input> action) => WrappedAction = action;
        public static implicit operator ActionWrapper<Input>(Action<Input> action) => new ActionWrapper<Input>(action);
    }

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

    public class DelegateWrapper<InOut> {
        private DoStuffDelegate<InOut> WrappedDelegate { get; }
        public DelegateWrapper(DoStuffDelegate<InOut> deleg) => WrappedDelegate = deleg;
        public static implicit operator DelegateWrapper<InOut>(DoStuffDelegate<InOut> deleg) => new DelegateWrapper<InOut>(deleg);
    }

    static void Main(string[] args) {
        // issue with Func:
        FunctionWrapper<string> funcWrapper1 = (Func<string>)(() => "hello"); // COMPILES - generates IDE0004 in visual studio => redundant cast
        //FunctionWrapper<string> funcWrapper2 = () => "hello"; // FAILS TO COMPILE CS1660 - IDE0004 above was wrong?

        // most strange part:
        var funcLambda = () => "hello";
        FunctionWrapper<string> funcWrapper3 = funcLambda; // NOW WORKS ?? - did 'funcLambda' definition involved any implicit conversion?

        // issue with action:
        ActionWrapper<string> actionWrapper1 = (Action<string>)((string s) => Console.WriteLine(s)); // COMPILES - generates IDE0004 in visual studio => redundant cast
        //ActionWrapper<string> actionWrapper2 = (string s) => Console.WriteLine(s); // FAILS TO COMPILE CS1660 - IDE0004 above was wrong?

        // most strange part:
        var actionLambda = (string s) => Console.WriteLine(s);
        ActionWrapper<string> actionWrapper3 = actionLambda; // NOW WORKS ?? - did 'actionLambda' definition involved any implicit conversion?

        // with delegates:
        DoStuffDelegate<string> deleg1 = (ref string Input) => { Input = Input + Input; }; // This works right away - no cast needed
        var delegateLambda = (ref string Input) => { Input = Input + Input; };
        //DoStuffDelegate<string> deleg2 = delegateLambda; // - DOES NOT COMPILE: CS0029
        //var deleg3 = (DoStuffDelegate<string>)(delegateLambda); // - DOES NOT COMPILE: CS0030
        var deleg4 = new DoStuffDelegate<string>(delegateLambda); // NOW WORKS... - why did the implict conversion above failed?

        DelegateWrapper<string> delegWrapper1 = (DoStuffDelegate<string>)((ref string Input) => { Input = Input + Input; }); // COMPILES - generates IDE0004 in visual studio => redundant cast
        //DelegateWrapper<string> delegWrapper2 = (ref string Input) => { Input = Input + Input; }; // FAILS TO COMPILE CS1660 - IDE0004 above was wrong?

        // This time, this doesn't work (probably because this requires two successive implicit conversions)
        //DelegateWrapper<string> delegWrapper3 = delegateLambda; // - DOES NOT COMPILE: CS0029
    }
}

(代码链接:https://godbolt.org/z/6xKscrzTK

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

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

提前谢谢您。

lambda implicit-conversion .net-7.0 c#-10.0 inferred-type
1个回答
0
投票

看起来像是

IDE0004
的问题。

您应该报告此问题

© www.soinside.com 2019 - 2024. All rights reserved.