开发者

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;
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜