.NET事件特殊方法(添加/删除/提升/其他)
我想知道EventInfo.GetRaiseMethod
和EventInfo.GetOtherMethods
方法。 显然,CLR支持4种与事件相关的方法:添加,删除,提升和“其他”。 但是在C#中创建的事件只有添加和删除 …我假设在VB中使用了raise ,因为你必须在声明自定义事件时指定一个RaiseEvent
方法,但显然情况并非如此: GetRaiseMethod
总是返回null。
那么,有谁知道:
- 如果一个事件从未被使用过,那么有一个与事件相关联的加法方法有什么意义呢? 是否有使用此方法引发事件的特定MSIL指令? (我在操作码中找不到类似的东西)
-
GetOtherMethods
返回的“其他”方法是什么(好吧,实际上没有返回)? 他们应该做什么? - BCL中有哪些类型可以实现这些特殊方法?
据我所知,加注并没有太多使用,我几乎从未见过它。 C ++ / CLI几乎是我所知道的唯一一种语言,可以很容易地声明一个raise方法。 请参阅此代码示例:
using namespace System; ref class Foo { private: Action ^bar; public: event Action ^Bar { void add (Action ^action) { Console::WriteLine ("add"); bar += action; } void remove (Action ^action) { Console::WriteLine ("remove"); bar -= action; } void raise () { Console::WriteLine ("raise"); if (!bar) return; Console::WriteLine ("raise for real"); bar->Invoke (); } }; }; void hello () { Console::WriteLine ("hello"); } void main () { Foo ^foo = gcnew Foo (); foo->Bar (); foo->Bar += gcnew Action (&hello); foo->Bar (); }
在运行时,自然输出:
C:\tmp>test raise add raise raise for real hello
要回答你的问题,没有操作码来调用事件,编译器只会调用raise方法:
IL_0020: ldloc.0 IL_0021: call instance void Foo::raise_Bar()
就像它发出add_Bar调用一样。
由于C#允许您仅在声明成员事件的类型范围内调用事件,因此无法获得C#代码来调用该raise方法,这也是值得的。 所以不,你不会在BCL中发现这样的方法。
至于.other
方法,我从来没有看到任何附加到事件。 我只看到它们曾经用于属性 ,而且“Inside IL汇编程序”和“CLI注释标准”这本书都没有提供有关它们的任何信息。 但基本上,它们允许您将方法附加到属性或事件以在语义上绑定它们。 它们既不是addon
,也不是removeon
addon
,也不是removeon
方法,但如果语言需要表达,它们将成为事件的一部分。 与此同时,发射一个的唯一方法是使用ilasm。
是的,C#可以使用add / remove重载来注册事件处理程序。 EventInfo
是解析类签名时使用的System.Reflection
元数据; Visual Basic中的RaiseEvent
方法不一定与此方法相同,因为reflection为您创建了一种动态调用事件或添加事件处理程序的方法。 RaiseEvent
类似于在C#中调用事件就像一个方法。
(这是一个部分答案,因为你的post中有问题我也不知道答案。)