【发布时间】:2011-01-27 11:26:09
【问题描述】:
在检查 C# 和 .NET 中的委托时,我注意到一些有趣的事实:
在 C# 中创建委托会创建一个从 MulticastDelegate 派生的类,并带有构造函数:
.method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed { }
意味着它需要实例和指向方法的指针。然而,在 C# 中构造委托的语法表明它有一个构造函数
new MyDelegate(int () target)
我可以将int () 识别为函数实例(int *target() 将是 C++ 中的函数指针)。所以很明显,C#编译器从函数名定义的方法组中挑选出正确的方法并构造委托。所以第一个问题是,C# 编译器(或者准确地说是 Visual Studio)从哪里选择这个构造函数签名?我没有注意到任何特殊属性或可以区分的东西。这是某种编译器/视觉工作室的魔法吗?如果不是,T (args) target 构造在 C# 中是否有效?我没有设法得到任何东西来编译,例如:
int() 目标 = 我的方法;
无效,对MyMetod 执行任何操作也是如此,例如在上面调用.ToString()(这确实有些道理,因为这在技术上是一个方法group,但我想应该可以通过强制转换显式选择一个方法,例如(int())MyFunction。那么所有这些纯粹的编译器魔法是什么?通过反射器查看构造揭示了另一种语法:
Func CS$1$0000 = new Func(null, (IntPtr) Foo);
这与反汇编的构造函数签名一致,但无法编译!
最后一个有趣的注意事项是 Delegate 和 MulticastDelegate 类还有另一组构造函数:
.method 系列 hidebysig specialname rtspecialname 实例 void .ctor(class System.Type target, string 'method') cil managed
从实例和方法指针到类型和字符串方法名称的转换发生在哪里?这可以通过自定义委托构造函数签名中的runtime managed 关键字来解释,即运行时是否在这里完成它的工作?
编辑:好的,所以我想我应该重新表述我想通过这个问题表达的意思。基本上,我建议在委托构造中不仅有 C# 编译器/CLR 魔法,还有一些 Visual Studio 魔法,因为 Intellisense 在建议构造函数参数时会翻转一些新语法,甚至隐藏其中一个它们(例如,反射器不使用这种语法和构造器)。
我想知道这个断言是否正确,函数实例语法在 C# 中是否有更深层次的含义,或者它只是 Visual Studio 魔术部分为清楚起见而实现的某种常量格式(这是有道理的,因为它看起来像无效C#) ?简而言之,如果我在实现 Intellisense,我应该为代表做一些魔术,还是可以通过一些巧妙的机制构建建议?
最终编辑:所以,普遍的共识是这确实是 VS 魔法。看到这种 VS 行为的其他示例(请参阅 Marc Gravell 的评论)让我相信确实如此。
【问题讨论】:
-
CS$1$0000是反编译器生成的,从不编译。 -
我知道,名字不是这里的重点,是新的结构不能编译。
-
是的,只是想指出。
标签: c# .net delegates clr .net-internals