About C# delegate/event processing
I have a simple program that doesn't behave the way I expected it to behave. I was under the impression that both Method Signatures would run in the order of the Invocation List of the Delegate during the CallEvent() method and make the Test Property equate to 40. Hence:
Test += (20+15);
Test += (20-15);
Test == 40;
As it would turn out, this assignment is equal to 5, which is the value of the subtraction. If it did the addition first then replaced it with subtraction, doesn't that defeat the purpose of the Test += assignment? Maybe it is bypassing the addition all together (however unlikely). I suspect something more inherent is going on that I just can't see with my current programming knowledge.
Please and Thank You! LiquidWotter
//MY NAMESPACE
namespace MyNamespace
{
//MAIN
private static void Main(string[] args)
{
//CREATE MY OBJECT
MyClass MyObject = new MyClass();
//ADD CALLS TO EVENT
MyObject.MyEvent += Add;
MyObject.MyEvent += Sub;
//CALL EVENT AND WRITE
MyObject.CallEvent(20, 15);
Console.WriteLine(MyObject.Test.ToString());
//PAUSE
Console.ReadLine();
}
//ADDITION
private static int Add(int x, int y)
{ return x + y; }
//SUBTRACTION
private static int Sub(int x, int y)
{ return x - y; }
//MY CLASS
public class MyClass
{
//MEMBERS
p开发者_如何学Pythonublic delegate int MyDelegate(int x, int y);
public event MyDelegate MyEvent;
public int Test { get; set; }
//CONSTRUCTOR
public MyClass()
{
this.Test = 0;
}
//CALL Event
public void CallEvent(int x, int y)
{
Test += MyEvent(x, y);
}
}
}
Well you are correct. There can only be one return value[1], while both delegates where called only one, in fact the last, returned its value. Which makes sense, because how should the framework know what to do in cases where you directly place your event in a method as an argument:
this.Foo( MyEvent(x, y) );
call Foo once or multiple times? somehow combine the values? You see it is not clear.
I have to add that the order of delegates is also not defined[2], well currently it is defined(The order of registration) but you should never rely on it.
Using the += operator adds a new delegate to the invokation chain. A chain is how it is evaluated. Each delegate will be invoked in order in the chain. But, because the delegates are all invoked (meaning they block and return a value to the caller) only the last result is returned in your assignment.
Assuming this example is a simplification, rather than having delegates with a result you could use a collection of lambda epxressions and Linq extensions to Sum
or simply maintain state in your class.
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
//MAIN
private static void Main(string[] args)
{
IEnumerable<Func<int, int, int>> operationsList =
new Func<int,int, int>[] { Add, Sub };
//CALL EVENTs AND WRITE
Console.WriteLine(operationsList.Sum(operation => operation(20, 15)));
//PAUSE
Console.ReadLine();
}
//ADDITION
private static int Add(int x, int y)
{
return x + y;
}
//SUBTRACTION
private static int Sub(int x, int y)
{
return x - y;
}
}
精彩评论