我刚发现一件奇怪的事情:
Action a1 = () => Console.Write("1 ");
Action a2 = () => Console.Write("2 ");
Action tmp = a1;
a1 += a2;
a2 = tmp;
Console.Write("a1:\t");
a1(); //a1: 1 2
Console.Write("\na2:\t");
a2(); //a2: 1
Console.ReadLine();
我希望两个陈述都返回" 1 2&#34 ;; 为什么不是这样?
答案 0 :(得分:3)
是的,代表是参考类型。它们也是不可变的,如System.String。这给很多人带来了惊喜。想象一下,你有相同的代码与字符串。我认为这更清楚:
String s1 = "1 ";
String s2 = "2 ";
String stmp = s1;
s1 += s2;
s2 = stmp;
Console.WriteLine(s1); // 1 2
Console.WriteLine(s2); // 1
调用+=
不会改变委托的基础实例,它会生成一个新的委托,右侧附加到新委托的调用列表中。 +=
实际上只是Delegate.Combine
的糖,编译器生成类似于以下内容的代码:
a1 = (Action)Delegate.Combine(a1, a2);
我认为我们正在创建一个新的委托实例。
答案 1 :(得分:0)
原因是您在添加附加事件之前已将临时变量分配给a1,后者修改了事件要执行的操作。如果你想要“1 2”的相同结果,你应该做到:
a1 += a2;
a2 = a1;
这会产生您期望的相同结果。另一种方法是你做了这样的事情:
a1 += a2;
Action temp = a1;
a2 = temp;
这也会导致你期待的结果。