关于C#委托/事件处理

时间:2011-10-01 02:04:12

标签: c# events delegates

我有一个简单的程序,它的行为与我预期的行为不同。我的印象是,在CallEvent()方法期间,两个Method Signatures都将以Delegate的Invocation List的顺序运行,并使Test Property等于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 个答案:

答案 0 :(得分:3)

你是对的。只能有一个返回值[1],而两个只调用一个的委托,实际上是最后一个,返回其值。这是有道理的,因为如果您直接将事件作为参数放在方法中,框架应该如何知道该怎么做:

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

拨打Foo一次或多次?以某种方式结合价值观?你看,目前尚不清楚。

我必须补充一点,委托的顺序也没有定义[2],目前已经定义了(注册顺序),但你永远不应该依赖它。

答案 1 :(得分:3)

使用+ =运算符向invokation链添加新委托。链是如何评估的。将在链中按顺序调用每个代理。但是,因为委托都被调用(意味着它们阻塞并向调用者返回一个值),所以只在作业中返回最后一个结果。

假设这个示例是一个简化,而不是让代表有结果,你可以使用lambda epxressions和Linq扩展的集合Sum或者只是在你的类中保持状态。

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