但是,我对该功能的行为感到非常困惑:
一般来说,我认为我们可以合理地预期,如果可以编译的话:
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)
我尝试了不同的编译器,并搜索了有关推断委托类型行为的文档、讨论和潜在已知问题,但没有成功。
有人可以告诉我这是否是语言/编译器缺陷,或者我对这些转换的期望是否不合理?
提前谢谢您。