Sau*_*tka 14 .net c# clr delegates .net-internals
在检查C#和.NET中的代表时,我注意到一些有趣的事实:
在C#中创建委托会创建一个MulticastDelegate使用构造函数派生的类:
Run Code Online (Sandbox Code Playgroud).method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed { }
这意味着它需要实例和指向该方法的指针.然而,在C#中构造委托的语法表明它有一个构造函数
Run Code Online (Sandbox Code Playgroud)new MyDelegate(int () target)
我可以将其识别int ()为函数实例(int *target() 将是C++中的函数指针).很明显,C#编译器从函数名定义的方法组中选出正确的方法并构造委托.所以第一个问题是,C#编译器(或者Visual Studio,准确地说)从哪里选择这个构造函数签名?我没有注意到任何可以区分的特殊属性或东西.这是某种编译器/ visualstudio魔术吗?如果没有,那么T (args) target结构在C#中是否有效?我没有设法用它来编译,例如:
int()target = MyMethod;
是无效的,所以做任何事情MyMetod,例如调用.ToString()它(这确实有一定意义,因为这在技术上是一个方法组,但我想应该可以通过强制显式选择一个方法,例如(int())MyFunction.所以所有这个纯粹的编译魔术?通过反射器看结构揭示了另一种语法:
Func CS $ 1 $ 0000 = new Func(null,(IntPtr)Foo);
这与反汇编的构造函数签名一致,但这不能编译!
最后一个有趣的注意事项是类Delegate和MulticastDelegate另外一组构造函数:
.method family hidebysig specialname rtspecialname instance void .ctor(类System.Type target,string'method')cil managed
从实例和方法指针到类型和字符串方法名称的转换发生在哪里?这可以通过runtime managed自定义委托构造函数签名中的关键字来解释,即运行时是否在此处执行此操作?
编辑:好的,所以我想我应该重新阐述我想通过这个问题说的话.基本上我建议不仅C#编译器/ CLR魔术涉及委托构造,而且还有一些Visual Studio魔术,因为Intellisense在建议构造函数参数时会翻转一些新语法甚至隐藏其中一个(例如Reflector不使用)这个语法和construtor,就此而言).
我想知道这个断言是否属实,以及函数实例语法在C#中是否具有更深层的含义,或者它只是为了清晰起见而由Visual Studio魔术部分实现的一些常量格式(这是有道理的,因为它看起来像无效的C#)?简而言之,如果我正在实施Intellisense,我应该为代表做一些魔术还是我可以通过一些聪明的机制构建建议?
最终编辑:所以,流行的共识是,这确实是VS魔术.看到这种VS行为的其他例子(参见Marc Gravell的评论)使我确信这是事实.
Mar*_*ell 12
第一个参数是从对象引用(或null静态方法)解析的; 没有魔法.
但是,第二个参数是 - 它是一个非托管指针(native int); 简而言之,没有可以使用此构造函数的替代直接 C#语法 - 它使用特定的IL指令(ldftn)来从元数据中解析函数.但是,您可以使用Delegate.CreateDelegate通过反射创建委托.你也可以使用IL发射(DynamicMethod等),但它并不好玩.