2011-10-01 100 views
2

我有一个简单的程序,其行为不像我预期的那样行为。我的印象是,这两个方法签名会在委托的调用列表的顺序CallEvent()方法的过程中运行,使测试属性等同于40.因此:关于C#委托/事件处理

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); 
     } 
    } 
} 
+1

你并不是真正按照他们的意图使用事件。如果你想存储一个委托,把它存储在一个变量中。这不是一个事件的作用。 –

+0

你偶然发现所有事件都应该是'void f(...)' –

回答

3

那么你是正确的。只能有一个返回值[1],而只调用一个的实际上是最后一个的代表返回了它的值。这是有道理的,因为该框架应如何知道在情况下,你直接把你的事件的方法作为参数做:

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

调用foo一次或多次?以某种方式结合了价值观?你看它不清楚。

我必须补充说,代表的顺序也没有定义[2],目前它已被定义(注册顺序),但你不应该依赖它。

+0

这就是我正在寻找的,谢谢你的参考。 :) –

3

使用+ =操作符将新代理添加到调用链。链是如何评估的。每个代表将在链中按顺序调用。但是,因为代表都被调用(意味着它们阻止并向调用方返回一个值),所以只有最后一个结果返回到您的任务中。

假设这个例子是一个简化,而不是委托人的结果,你可以使用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; 
    } 
} 
+0

这是真正解决程序问题的好方法!但是,我的问题是关于代表和事件的性质。我很困惑他们为什么没有按我预期的方式工作。 :) –

+0

+1为了给出一个替代方案,这是我的文章中缺少的东西。 – dowhilefor