使用+组合method group触发CS0019编译错误的技术咨询
为什么用
+组合两个方法组会触发CS0019错误,而+=可以正常实现多播委托? 报错代码示例
public class TypeTests { delegate int LogMessageDelegate(string message); int LogMessageToConsoleReturn1(string msg) { Console.WriteLine($"{msg} return 1"); return 1; } int LogMessageToConsoleReturn2(string msg) { Console.WriteLine($"{msg} return 2"); return 2; } [Fact] public void DelegateInvokesMethod() { LogMessageDelegate log; // log = LogMessageToConsoleReturn1; // assign to a method group // log += LogMessageToConsoleReturn2; // multicast using += works just fine log = LogMessageToConsoleReturn1 + LogMessageToConsoleReturn2; // multicast using + causes CS0019 compiler error Assert.Equal(2, log("Hello")); } }
这段代码会触发CS0019编译错误,错误信息为:
运算符“+”无法应用于“方法组”和“方法组”类型的操作数
正常运行的代码示例
修改为以下形式后,代码可正常编译、运行并通过测试:
public class TypeTests { delegate int LogMessageDelegate(string message); int LogMessageToConsoleReturn1(string msg) { Console.WriteLine($"{msg} return 1"); return 1; } int LogMessageToConsoleReturn2(string msg) { Console.WriteLine($"{msg} return 2"); return 2; } [Fact] public void DelegateInvokesMethod() { LogMessageDelegate log; log = LogMessageToConsoleReturn1; // assign to a method group log += LogMessageToConsoleReturn2; // multicast using += works just fine // log = LogMessageToConsoleReturn1 + LogMessageToConsoleReturn2; // multicast using + causes CS0019 compiler error Assert.Equal(2, log("Hello")); } }
原因解释
- 方法组与委托实例的区别:方法组(比如
LogMessageToConsoleReturn1)不是委托实例,它是匹配委托签名的方法集合引用。只有在特定上下文(比如赋值给委托变量)中,编译器才会自动将方法组隐式转换为对应的委托实例。 +运算符的限制:+是委托实例之间的运算符,要求两边必须是已存在的委托实例,无法直接作用于两个方法组——编译器不会自动对两个方法组同时做隐式转换来支持+运算。+=运算符的特殊处理:当执行log += LogMessageToConsoleReturn2时,log已经是一个委托实例(之前通过log = LogMessageToConsoleReturn1完成了方法组到委托的隐式转换)。此时+=会先把右边的方法组隐式转换为委托实例,再和左边的委托实例组合,最终赋值回log。简单来说,+=的上下文已经有一个委托实例,编译器明确知道要把右边的方法组转成委托,而+两边都是方法组时,编译器无法完成这种转换。
内容的提问来源于stack exchange,提问作者joseville
相关产品推荐
相关产品推荐

