代表充当价值类型

时间:2014-10-16 05:29:02

标签: c# delegates

我刚发现一件奇怪的事情:

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 ;; 为什么不是这样?

2 个答案:

答案 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;

这也会导致你期待的结果。