委托
我们先来说说委托的使用和语法,然后再说概念
声明一个委托变量,这个委托可以在类外面,命名空间内,范围很广泛
using System;namespace ConsoleApp1
{//声明一个委托,无返回值带参数的public delegate void sayHelloDlg(string name);class Program{private static void Main(string[] args){}}
}
声明一个委托后,我们还是写一个对应的方法,才能给他赋值,这个方法的返回值和参数格式都要和委托一致
using System;namespace ConsoleApp1
{//声明一个委托,无返回值带参数的public delegate void sayHelloDlg(string name);class Program{private static void Main(string[] args){}//委托对应的函数public static void sayHello(string name){Console.WriteLine($"{name},你好呀");}}
}
之后我们可以对其赋值,调用,执行之后控制台会输出(张三,你好呀)
private static void Main(string[] args)
{//委托赋值的方法必须返回值和参数的格式一致//将方法以变量的形式传递,并且以方法的形式执行,多数用于回调函数sayHelloDlg dlg = new sayHelloDlg(sayHello);dlg("张三");Console.ReadKey();
}
除此之外呢,还有委托链,即一个委托可以绑定多个方法
通过+=和-=来操作委托链
或者Delegate.Combine(事件, 新的方法)和Delegate.Remove(事件, 要删除的方法);
private static void Main(string[] args)
{//委托赋值的方法必须返回值和参数的格式一致//将方法以变量的形式传递,并且以方法的形式执行,多数用于回调函数sayHelloDlg dlg = new sayHelloDlg(sayHello);//委托链,可以通过+=和-=来进行多个委托赋值dlg += sayGoodBye;dlg -= sayHello;dlg("张三");Console.ReadKey();
}
除了提前写好方法,我们还可以用匿名函数
private static void Main(string[] args)
{//委托赋值的方法必须返回值和参数的格式一致//将方法以变量的形式传递,并且以方法的形式执行,多数用于回调函数sayHelloDlg dlg = new sayHelloDlg(sayHello);//委托链,可以通过+=和-=来进行多个委托赋值dlg += sayGoodBye;dlg -= sayHello;//匿名函数绑定,这里用的是=,所以前面的所有绑定的方法都清空,只保留这一个匿名函数了dlg = delegate (string name){Console.WriteLine($"{name},我是匿名函数");};//用lamda表达式来帮写匿名函数dlg = (string name) =>{Console.WriteLine($"{name},我是lamda表达式");};dlg("张三");Console.ReadKey();
}
以上就是委托的使用
通过上面代码可以总结出,委托是一种类,引用类型的数据类型。它有返回值类型和参数列表,可以指向一个或多个方法。
当实例化委托后(即创建了一个委托的实例),这个委托类型的实例可以和任何其他方法关联起来,存储这些方法的引用,接着就可以通过委托类型的实例 间接调用这些存储的方法,通过委托我们可以将方法像引用类型一样传递,距离框架的回调函数,都可以通过委托实现
事件
接下来我们看看事件的使用
使用事件之前,还是要先声明个委托
事件是属于类的一个属性,不像委托那样可以声明在命名空间内,给事件赋值也可以使用+=和-=进行多个赋值
namespace ConsoleApp1
{//声明一个委托,无返回值带参数的public delegate void sayHelloDlg(string name);class Program{//声明一个事件public static event sayHelloDlg sayHelloEvent;private static void Main(string[] args){sayHelloEvent += sayHelloPar;if (sayHelloEvent != null)sayHelloEvent("李四");Console.ReadKey();}}
}
通过代码我们可以理解为事件是委托的细分,委托范围大,事件可以将委托细分到分割分类里
委托和事件的区别
尽管事件和委托有许多共同点,但它们在概念上和使用上有一些区别。委托更多地被看作是一种引用方法的机制,而事件则是一种基于委托的通信机制,允许对象发布通知,其他对象可以订阅这些通知。
在实际应用中,事件通常用于实现发布-订阅模式,允许多个对象对同一事件作出响应,而委托则用于定义这些响应的方法。例如,在图形用户界面编程中,按钮点击可以是一个事件,而事件处理程序是一个委托,定义了当按钮被点击时应该执行的方法。
委托呢更是一种类型,比如参数传递,类型可以是委托但是不能是事件
事件呢他只能属于类,所以他比较安全,不会像委托那么广泛,更方便独立管理,避免类之外调用
概念和用途:
委托:委托是一种类型安全的引用,用于封装方法。它允许将方法作为参数传递给其他方法,或者存储和调用一组方法。委托允许类似于函数指针的功能,但在C#中更加类型安全和面向对象。
事件:事件是委托的一种特殊应用,用于实现发布-订阅模型。事件提供了一种通知机制,允许对象通知其他对象发生了特定的动作或状态改变。通过事件,一个对象(事件源)可以告知其他对象(事件订阅者)已经发生了某个行为或状态。
使用方式:
委托:委托可以直接通过实例化委托类型并调用其方法来使用,也可以通过 += 和 -= 运算符来添加和移除方法引用。
事件:事件(Event)本质上是委托(Delegate)的一种特殊用法。在C#中,事件通过声明一个委托类型的变量,然后使用 event 关键字来创建。这样做的目的是为了限制对委托调用列表的访问,只允许外部代码订阅(使用 +=)和取消订阅(使用 -=)事件,而不允许直接调用委托或修改调用列表。
安全性和封装:
委托:委托的调用列表可以被外部直接访问和修改,因此需要在使用时谨慎处理以确保类型安全和代码健壮性。
事件:事件封装了委托的调用过程,外部代码不能直接调用或修改事件的触发逻辑,只能通过提供的订阅和取消订阅方法来操作事件。
适用场景:
委托:适合在需要将方法作为参数传递或需要多播委托(即一个委托可以引用多个方法)的场景中使用。
事件:适合实现发布-订阅模式,特别是在GUI编程、多线程编程、异步编程等需要对象之间解耦的情况下。