在C#中,我发现自己偶尔想要在发送同一事件的过程中为事件注册一个方法。例如,如果我有一个基于相同事件的连续调度转换状态的类,我可能希望第一个状态的处理程序取消注册自身并注册第二个处理程序。但是,我不想在下次触发事件之前调度第二个处理程序。
好消息是,C#的Microsoft实现看起来就像这样。事件注册语法sugar被调用System.Delegate.Combine替换,System.Delegate.Combine只将当前调用列表和新方法连接到一个单独的列表中,并将其分配给事件属性。这给了我我想要的行为。
所以,我的问题是:这是语言标准的保证行为吗?我希望能够在单声道的其他平台上运行我的C#代码,并且通常希望确保我不会根据其实现对语言标准做出假设。
我在MSDN上找不到任何明确的信息。
如果你想要我所谈论的具体例子,这里有一个例子:
delegate void TestDelegate();
static event TestDelegate TestEvent;
static void Main (string[] args) {
TestEvent += TestDelegateInstanceFirst;
TestEvent();
TestEvent();
}
static void TestDelegateInstanceFirst () {
Console.WriteLine("First");
TestEvent += TestDelegateInstanceSecond;
}
static void TestDelegateInstanceSecond () {
Console.WriteLine("Second");
}
至少在Windows上,输出是:
First
First
Second
答案 0 :(得分:8)
是的,这是有保障的。
从统一的C#3.0规范,第15.1节:
但是,当两个非null委托时 实例合并,他们的 调用列表是连接在一起的 顺序左操作数然后右 操作数 - 形成一个新的调用列表, 其中包含两个或更多条目。
请注意“新调用列表”。再次在第15.3节中:
实例化后,委托实例 总是引用相同的目标对象 和方法。记住,当两个 代表合并,或者一个是 从另一个人那里移除一名新代表 结果有自己的调用列表; 代表的调用列表 合并或删除保持不变。
最后,System.Delegate的MSDN声明:
代表是不可改变的;一旦创建, 委托的调用列表 不要改变。
我怀疑CLI规范中有一些东西 - 我会检查你是否喜欢,但希望这三个给你足够的信心:)