C#中委托和事件

发布时间 2023-12-22 14:59:19作者: SamaHddd

1.委托

在C#中,我们可以认为委托是持有一个或者多个方法的对象。简单来说,就是它可以将方法当作参数进行传递,类似于C/C++中的指针。我们在C#中定义委托需要使用delegate关键字。

下面是一个简单的委托示例:

public delegate int DelegateDemo(int x,int y);//定义了一个委托
class Demo_1
{
    public static void Main()
    {
        DelegateDemo delegateDemo_1=new DelegateDemo(AddValue);//将委托指向AddValue这个方法,并进行相关操作
        int x=delegateDemo_1(20,10);
        System.Console.WriteLine(x);
 
        DelegateDemo delegateDemo_2=new DelegateDemo(SubValue);//将委托指向SubValue这个方法,并进行相关操作
        int y=delegateDemo_2(20,10);
        System.Console.WriteLine(y);
        
    }
 
    public static int AddValue(int x,int y)//与委托匹配的一个方法
    {
        return x+y;
    }
    public static int SubValue(int x,int y)//与委托匹配的另一个方法
    {
        return x-y;
    }
}

上述代码的输出结果为:30 10

需要注意的是,委托是类型,就好像类是类型一样。与类一样,委托类型必须在被用来创建变量以及类型的对象之前声明。委托类型的声明看上去与方法的声明很相似,有返回类型和签名。返回类型和签名指定了委托接受的方法的形式。

C#提供了可以为委托添加方法的语法,即使用+=运算符。

下面是一个示例:

public delegate void DelegateDemo(int x);
class Demo_1
{
    public static void Main()
    {
        DelegateDemo delegateDemo=null;
        delegateDemo+=MulValue;
        delegateDemo+=DivValue;
        delegateDemo(10);
    }
    public static void MulValue(int x)
    {
        System.Console.WriteLine(2*x);
    }
    public static void DivValue(int x)
    {
        System.Console.WriteLine(x/2);
    }
}

上述代码的输出结果为:20 5

当然,在使用+=运算符时,实际发生的是创建了一个全新的委托。

事实上,在绝大部分情况下,我们不用自己声明委托。微软官方给我们写好了两种委托:Action和Func。其中,Func代表有返回值的委托,Action代表无返回值的委托。

 

2.事件

事件可以理解为一种特殊的委托。事件提供了一种机制,允许一个对象(称为发布者)通知其他对象(称为订阅者或监听者)发生了特定的动作或状态变化。

下面是定义一个事件的代码:

 
        public delegate void DelegateDemo(int x);//定义一个委托
        
        public event DelegateDemo emd;//定义一个事件

.NET框架提供了一个标准模式,该标准模式的基础就是System命名空间中声明的EventHandler委托类型。EventHandler委托类型的声明如下代码所示:

public delegate void EventHandler(object sender,EventArgs e);//sender:事件的传递者  e:传递的参数
 
public event EventHandler EventDemo;//使用

下面是一个简单使用事件的示例:

class Demo1
{
    static void Main()
    {
        var demo2=new Demo2();
        demo2.DemoEvent+=(demo2,e)=>
        {
            System.Console.WriteLine(1);
        };
        demo2.InvokeEvent();
    }
    
}
class Demo2
{
    public event EventHandler DemoEvent;
    public void InvokeEvent()
    {
        DemoEvent(this,null);
    }
}

输出结果为:1

1.Demo2 类中定义了一个名为 DemoEvent 的事件,该事件使用 EventHandler 委托,该委托的签名是 void EventHandler(object sender, EventArgs e)。这意味着事件可以携带无参数的信息。

2.Demo2 类中有一个名为 InvokeEvent 的方法,该方法在被调用时触发 DemoEvent 事件。在这里,DemoEvent 事件被触发时传递的参数是 this 和 null。

3.在 Demo1 类的 Main 方法中,创建了一个 Demo2 类的实例 demo2,然后订阅了 DemoEvent 事件。当 DemoEvent 事件被触发时,事件处理程序将输出 "1"。

4.最后,调用了 demo2.InvokeEvent() 来触发事件,因此会执行事件处理程序。

在实际应用中,事件通常用于在对象之间建立松散的耦合,以便对象能够在发生某些事情时通知其他对象,并执行相应的操作。