关于c#委托/事件处理

本文关键字:事件处理 委托 关于 | 更新日期: 2023-09-27 18:10:22

我有一个简单的程序,它的行为不像我期望的那样。在我的印象中,两个方法签名将在CallEvent()方法期间按照委托调用列表的顺序运行,并使Test属性等于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);
        }
    }
}

关于c#委托/事件处理

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

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

调用Foo一次还是多次?以某种方式把价值结合起来?你看不清楚。

我必须补充的是,委托的顺序也没有定义[2],目前它是定义的(注册的顺序),但你不应该依赖它

使用+=操作符向调用链添加一个新的委托。一个链是如何求值的。每个委托将在链中按顺序调用。但是,由于所有委托都被调用(这意味着它们阻塞并向调用者返回一个值),因此在分配中只返回最后一个结果。

假设这个例子是一个简化,而不是委托的结果,你可以使用一组lambda表达式和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;
    }
}