关于代表的澄清

时间:2011-10-20 03:38:37

标签: c# .net delegates

以下代码在做什么?我认为指针将改为multiply方法。 但是在这里做什么是“+ =”。我很困惑。

    delegate int calc(int a , int b);

    static void Main(string[] args)
    {
        calc c = new calc(Add);
        c += new calc(Multiply);
        Console.WriteLine(c(3, c(4, 2)));
        Console.Read();
    }

    public static int Add(int a, int b)
    {
        return (a + b);
    }

    public static int Multiply(int a, int b)
    {
        return (a * b);
    }

4 个答案:

答案 0 :(得分:4)

+和+ =运算符

与使用+运算符添加值的方式类似,您可以使用+=运算符添加并分配回相同的值。

应用于int的这些运算符的示例:

int a = 5;
a += 7; // a is now 12
a = a + 11;
Console.WriteLine(a);
  

24

合并代表

如AVD所述,你是use the + and += operators to combine delegates

当你将这些运算符应用于代理时,你没有做数学“总和”或“求和分配”,就像我的int s的例子。相反,您正在修改调用委托时要调用的方法列表。

从那篇文章:

  

可以组合代表,以便在调用委托时调用整个方法列表 - 可能使用不同的目标

因此,当你添加/组合代表时,你最终会调用多个方法。

如果您将代码更改为:

public static int Add(int a, int b)
{
    Console.WriteLine("From Add");
    return (a + b);
}

public static int Multiply(int a, int b)
{
    Console.WriteLine("From Multiply");
    return (a * b);
}

然后,当您运行程序时,您将看到此输出:

  

来自添加
  来自Multiply
  从添加
  来自Multiply
  24

这是因为:

  • 您合并了AddMultiply个代表,因此当您致电c(x, y)
  • 时,两个代表都会被调用
  • Multiply是您添加到该代理链中的最后一个代理
  • 您正在拨打c(x, y)两次。这类似于您调用:Multiply(3, Multiply(4, 2))

从合并代表返回值

关于您添加到链中的最后一个委托的那一点也在文章中提到:

  

如果声明委托类型返回一个值(即它没有使用void返回类型声明)并且调用了一个组合的委托实例,那么从该调用返回的值是列表中最后一个简单委托返回的值

您添加到链中的最后一个方法是Multiply,因此抛出所有其他返回值,并且在您调用Multiply时仅使用c(x, y)的返回值。< / p>

您可以在程序中看到这一点。 3 * 4 * 2是24,这是您程序的输出。您对Add的所有电话都不会影响最终结果。

答案 1 :(得分:2)

+ =就像是对委托对象附加多个调用。由于它是多播委托,您可以将多个目标调用附加到单个委托。要附加到委托,您需要新的委托对象。这就是第二行。

与之类似,

CalcDelegate C1, C2;
C1 = new CalcDelegate(Add);
C2 = new CalcDelegate(Multiply);
C1 = C1 + C2;

答案 2 :(得分:0)

它被称为Combining the delegates

答案 3 :(得分:0)

您可以将委托视为值类型(如intdouble)与方法地址数组之间的交叉。

你知道如果你写这段代码:

var x = 5;
var y = x + 2;
y += 3;

之后x == 5&amp; y == 10即使y的中间值为7,但在最终分配发生时,这会被“抛弃”。

很明显y 的最终价值不是 3

在你的代码中你写了这个:

calc c = new calc(Add);
c += new calc(Multiply);

y一样,c 的最终值不是 Multiply。它真的更像是这样:

c == { Add, Multiply }

当您拨打c(4, 2)之类的内容时,您实际上正在呼叫 Add&amp; Multiply并且因为委托返回一个值,您只返回最终委托的值 - 在本例中来自Multiply - 这就是“指针”变为Multiply的原因方法

您可以在致电c之前尝试添加此代码:

c -= new calc(Multiply);

这将有效地将c返回到此:

c == { Add }

这就是委托似乎表现得像方法地址数组的原因。

现在,如果您更改Add&amp; Multiply方法看起来像这样:

public static int Add(int a, int b)
{
    Console.WriteLine("Add({0}, {1})", a, b);
    return (a + b);
}

public static int Multiply(int a, int b)
{
    Console.WriteLine("Multiply({0}, {1})", a, b);
    return (a * b);
}
然后,您可以在发生呼叫时观看呼叫。您的原始代码运行如下:

Add(4, 2)
Multiply(4, 2)
Add(3, 8)
Multiply(3, 8)
24

我希望这会有所帮助。