О делегировании C # / обработке событий - PullRequest
2 голосов
/ 01 октября 2011

У меня есть простая программа, которая ведет себя не так, как я ожидал.У меня сложилось впечатление, что обе сигнатуры метода будут выполняться в порядке списка вызовов делегата во время метода CallEvent (), и свойство теста будет равно 40. Следовательно:

Test += (20+15);
Test += (20-15);
Test == 40;

Как это будетОказывается, это назначение равно 5, что является значением вычитания.Если он сначала сделал сложение, а затем заменил его вычитанием, разве это не противоречит цели назначения Test + =?Может быть, это обходить сложение все вместе (хотя вряд ли).Я подозреваю, что происходит нечто более неотъемлемое, чего я просто не вижу с моими текущими знаниями в области программирования.

Пожалуйста и спасибо!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
        public 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);
        }
    }
}

Ответы [ 2 ]

3 голосов
/ 01 октября 2011

Использование оператора + = добавляет нового делегата в цепочку вызовов.Цепочка - это то, как она оценивается.Каждый делегат будет вызываться по порядку в цепочке.Но, поскольку все делегаты вызываются (то есть они блокируют и возвращают значение вызывающей стороне), только последний результат возвращается в вашем назначении.

Предполагая, что этот пример является упрощением, вместо делегатов с результатом вы можете использовать коллекцию лямбда-выражений и расширений Linq для Sum или просто поддерживать состояние в вашем классе.

3 голосов
/ 01 октября 2011

Ну, вы правы. Может быть только одно возвращаемое значение [1] , в то время как оба делегата, вызвавшие только один, фактически последний, вернули свое значение. Это имеет смысл, потому что как фреймворк должен знать, что делать в тех случаях, когда вы непосредственно помещаете свое событие в метод в качестве аргумента:

  this.Foo( MyEvent(x, y) );

вызывать Foo один или несколько раз? как-то объединить значения? Вы видите, это не ясно.

Я должен добавить, что порядок делегатов также не определен [2] , в настоящее время он определен (порядок регистрации), но вы никогда не должны полагаться на него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...