Reputation: 1813
What is the below code doing? I think the pointer will be changed to the multiply method. But what is "+=" doing here. I am confused.
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);
}
Upvotes: 3
Views: 134
Reputation: 117019
You can think of delegates as a cross between value types (like int
or double
) and arrays of method addresses.
You know that if you write this code:
var x = 5;
var y = x + 2;
y += 3;
Then afterwards x == 5
& y == 10
even though y
had an intermediate value of 7
this was "thrown away" when the final assignment occurred.
Quite clearly the final value of y
isn't 3
.
In your code you wrote this:
calc c = new calc(Add);
c += new calc(Multiply);
As with y
, the final value of c
isn't Multiply
. It's really more like this:
c == { Add, Multiply }
When you then call something like c(4, 2)
you are effectively calling both Add
& Multiply
and because the delegate returns a value you only get back the final delegate's value - in this case from Multiply
- and that's what makes it appear that the "pointer" changed to the Multiply
method.
You could try adding in this code before you call c
:
c -= new calc(Multiply);
and this will effectively return c
back to this:
c == { Add }
And this is why delegates appear to behave like arrays of method addresses.
Now if you change your Add
& Multiply
methods to look like this:
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);
}
you can then watch the calls as they occur. Your original code runs like this:
Add(4, 2)
Multiply(4, 2)
Add(3, 8)
Multiply(3, 8)
24
I hope this helps.
Upvotes: 0
Reputation: 59101
The + and += operator
Similar to how you use the +
operator to add values, you can use the +=
operator to both add and assign back to the same value.
An example of these operators applied to int
s:
int a = 5;
a += 7; // a is now 12
a = a + 11;
Console.WriteLine(a);
24
Combining delegates
As AVD mentioned, you use the +
and +=
operators to combine delegates.
When you apply these operators to delegates, you aren't doing a mathematical "sum" or "sum and assign", like my example with int
s. Instead you are modifying a list of methods to be called when you invoke the delegate.
From that article:
Delegates can be combined such that when you call the delegate, a whole list of methods are called - potentially with different targets
So when you add/combine delegates, you'll end up calling multiple methods.
If you change your code to:
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);
}
Then you will see this output when you run the program:
From Add
From Multiply
From Add
From Multiply
24
This is because:
Add
and Multiply
delegates, so both get called when you call c(x, y)
Multiply
is the last delegate you added to that chain of delegatesc(x, y)
twice. This is similar to if you had called: Multiply(3, Multiply(4, 2))
Return values from combined delegates
That point about the last delegate you added to the chain is also mentioned in the article:
If a delegate type is declared to return a value (i.e. it's not declared with a void return type) and a combined delegate instance is called, the value returned from that call is the one returned by the last simple delegate in the list.
The last method you added to the chain was Multiply
, so all other return values are thrown out, and only the return value from Multiply
is used when you call c(x, y)
.
You can see this demonstrated in your program. 3 * 4 * 2
is 24, which is your program's output. None of your calls to Add
impact the final result.
Upvotes: 4
Reputation: 1919
+= is like appending multiple calls to the delegate object. Since its a multicast delegates, you can append multiple destination calls to the a single delegate. To append to a delegate, you need new delegate objects. And thats whats been doing in the second line.
Its similar to,
CalcDelegate C1, C2;
C1 = new CalcDelegate(Add);
C2 = new CalcDelegate(Multiply);
C1 = C1 + C2;
Upvotes: 2