在检查C#和.NET中的委托时,我注意到了一些有趣的事实:
在C#中创建委托会创建一个派生自MulticastDelegate
的类,并带有一个构造函数:
.method public hidebysig specialname rtspecialname instance
void .ctor(object 'object', native int 'method') runtime managed { }
意味着它需要实例和方法的指针。然而,在C#中构造委托的语法表明它有一个构造函数。
在C#中,我们可以将new MyDelegate(int () target)
int()
识别为函数实例(在C++中,int *target()
则是一个函数指针)。显然,C#编译器从由函数名定义的方法组中挑选出正确的方法并构造委托。那么第一个问题是,C#编译器(或者确切地说是Visual Studio)从哪里获取这个构造函数签名?我没有注意到任何特殊的属性或者东西可以进行区分。这是一种编译器/Visual Studio的魔法吗?如果不是,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(class System.Type target, string 'method') cil managed
runtime managed
关键字来解释,即运行时是否在这里发挥作用?编辑:我想表达的是,委托构造不仅涉及到C#编译器/CLR的魔法,还涉及到一些Visual Studio的魔法,因为Intellisense在建议构造函数参数时会翻转出一些新的语法,并隐藏其中一个参数(例如Reflector没有使用这个语法,事实上也没有使用这个构造函数)。我想知道这种说法是否正确,以及函数实例语法在C#中是否有更深层次的含义,还是只是由Visual Studio魔法部分实现的常量格式,以提高可读性(这有意义,因为它看起来像无效的C#代码)?简而言之,如果我正在实现Intellisense,我需要为委托做一些魔法,还是可以通过一些聪明的机制构造建议?最终编辑:那么,普遍的共识是这确实是Visual Studio的魔法。看到其他类似的例子(请参见Marc Gravell的评论)证明了这一点。
CS$1$0000
是反编译生成的,无法编译。 - Dykam