我有这个简单的事件:
public class ClassA
{
public event Func<string, int> Ev;
public int Do(string l)
{
return Ev(l);
}
}
Run Code Online (Sandbox Code Playgroud)
和2方法:
static int Display(string k)
{
return k.Length;
}
static int Display_2(string k)
{
return k.Length*10;
}
Run Code Online (Sandbox Code Playgroud)
我正在注册这个活动:
ClassA a = new ClassA();
a.Ev += Display;
a.Ev += Display_2;
Run Code Online (Sandbox Code Playgroud)
现在,我正在执行:
Console.WriteLine(a.Do("aaa"));
Run Code Online (Sandbox Code Playgroud)
输出 :

什么 ???
他在调用列表中有2种方法!它确实运行了它们,但为什么它只显示上次注册的结果?
结果在哪里"3"消失了?(第一次调用)?(虽然两个display+都display_2被执行了......我没想到console.write会迭代结果.但也没想到他决定要显示哪个.)

这里有三个方面:
对于第1点,您有一个类似字段的事件.C#4规范的第10.8.1节给出了一个例子,并说明:
在
Button类的声明之外,该Click成员只能在+=和-=运算符的左侧使用,如Run Code Online (Sandbox Code Playgroud)b.Click += new EventHandler(...);它将一个委托附加到
Click事件的调用列表中
(强调我的).该规范还清楚地表明,类似字段的事件会创建一个委托字段,该字段在类中用于调用.
更一般地说(第2点),C#4规范的第7.8.4节谈到代表组合通过+和+=:
代表组合.每个委托类型隐式提供以下预定义运算符,其中
D是委托类型:Run Code Online (Sandbox Code Playgroud)D operator +(D x, D y)
+当两个操作数都是某种委托类型时,二元operato执行委托组合D.[...跳过其中x或y为空的位...]否则,操作的结果是一个新的委托,当被调用时,调用第一个操作数然后调用第二个操作数.
(再次强调我的.)
最后,第3点 - 事件调用和返回值.C#规范的第15.4节规定:
如果委托调用包括输出参数或返回值,则它们的最终值将来自列表中最后一个委托的调用.
更一般地说,它取决于事件的实现.如果您使用使用"正常"委托组合/删除步骤的事件实现,则一切都得到保证.如果你开始编写一个做疯狂事情的自定义实现,那就不一样了.
调用多播非void委托会返回已执行的最后一个处理程序的值.
你几乎无法控制谁是第一个或最后一个.这是一个糟糕的系统使用.
这就是大多数活动和代表回归的原因void.
| 归档时间: |
|
| 查看次数: |
568 次 |
| 最近记录: |