隐式和显式委托创建之间的区别(有和没有generics)
请参阅下面的Go()方法中的四行:
delegate void Action(T arg); delegate void Action(); void DoSomething(Action action) { //... } void DoSomething(Action action) { //... } void MyAction(T arg) { //... } void MyAction() { //... } void Go() { DoSomething(MyAction); // throws compiler error - why? DoSomething(new Action(MyAction)); // no problems here DoSomething(MyAction); // what's the difference between this... DoSomething(new Action(MyAction)); // ... and this? }
请注意,第一次调用生成的编译器错误是: 无法从用法推断出方法“Action(T)”的类型参数。 尝试显式指定类型参数。
MyAction
和new Action(MyAction)
之间没有区别(当它们都有效时),除了前者在C#1中不起作用。这是implicit method group conversion
。 有些时候这是不适用的,最值得注意的是当编译器无法确定你想要什么样的委托时,例如
Delegate foo = new Action(MyAction); // Fine Delegate bar = MyAction; // Nope, can't tell target type
这会在您的问题中发挥作用,因为所涉及的两种方法都会过载。 这基本上导致了头痛。
至于generics方面 – 这很有趣。 方法组没有得到C#3类型推断的太多爱 – 我不确定它是否会在C#4中得到改进。 如果您调用generics方法并指定类型参数,则类型推断可以很好地工作 – 但如果您尝试以相反的方式执行此操作,则会失败:
using System; class Test { static void Main() { // Valid - it infers Foo DoSomething (Foo); // Valid - both are specified DoSomething (Foo ); // Invalid - type inference fails DoSomething(Foo ); // Invalid - mismatched types, basically DoSomething (Foo); } static void Foo(T input) { } static void DoSomething (Action action) { Console.WriteLine(typeof(T)); } }
C#3中的类型推断非常复杂,并且在大多数情况下运行良好(特别是它对LINQ很有用)但在其他一些情况下失败。 在理想的世界中,它将变得更容易理解, 并且在未来的版本中更强大……我们会看到!
非generics隐式委托创建只是语法糖,因此编译器生成完全相同的代码
DoSomething(MyAction);
和
DoSomething(new Action(MyAction));
因为它可以直接从方法参数和上下文推断出委托的类型。
使用通用委托,您必须根据协方差和逆变指定委托类型(有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/ms173174(VS.80).aspx ) – T in Action可以是方法中T的超类型,它仍然可以作为委托方法接受。 因此,您需要在委托中明确指定T,因为编译器无法自行解决。
只是一个旁注..出于某种原因,这适用于VB。
当我将Methodgroup / adderessof转换为委托时,似乎C#中的预处理器的实现和VB不同。
上述就是C#学习教程:隐式和显式委托创建之间的区别(有和没有generics)分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请点击右边联系管理员删除。
如若转载,请注明出处:https://www.ctvol.com/cdevelopment/1004823.html