委托
可以理解为函数的指针
代码示例:
csharp
class Program
{
//定义委托
public delegate void StudyDelegate(string name);
//定义方法
public static void Math(string name)
{
Console.WriteLine(name + "学习数学");
}
public static void English(string name)
{
Console.WriteLine(name + "学习英文");
}
static void Main(string[] args)
{
//委托绑定方法
StudyDelegate studyDelegate = Math;
//委托绑定多个方法
studyDelegate += English;
//掉用委托
studyDelegate.Invoke("小明");
//通过内置Action方法实现委托
Action<string> studyDelegate2 = Math;
studyDelegate2 += English;
studyDelegate.Invoke("小明");
Console.ReadKey();
}
}
public delegate void StudyDelegate(string name); 通过关键字delegate声明是委托对象
通过+=,-= ,对委托对象实现方法的绑定和方法的移除
Action< T >, Func<T,TResult>,内置方法,实现委托,Action无返回值,Func有返回值
事件
特殊的委托机制,将委托的访问权限限制起来,开发者只需要通过+=,-=进行方法的订阅和取消订阅
代码示例:
csharp
class Program
{
//定义委托
public delegate void StudyDelegate(string name);
public static event StudyDelegate StudyEvent;
public static void Study(string name)
{
StudyEvent?.Invoke(name);
}
//定义方法
public static void Math(string name)
{
Console.WriteLine(name + "学习数学");
}
public static void English(string name)
{
Console.WriteLine(name + "学习英文");
}
static void Main(string[] args)
{
StudyEvent += Math;
StudyEvent += English;
Study("小明");
}
}
一版情况下,委托的对象会包含sender,eventArg等,代表穿过来的对象,对象参数等,类似winform中控件的事件。如下代码示例:
csharp
class Program
{
static void Main(string[] args)
{
Publish publish = new Publish();
//无数据传输事件
publish.publishHandler += (sendr, e) =>
{
Console.WriteLine("事件绑定方法1");
};
publish.Raise();
//数据传输事件
publish.publishHandler_cus += (sendr, e) => { Console.WriteLine("参数msg:" + e.msg); };
publish.Raise_cus("自定义参数");
Console.ReadKey();
}
}
//自定义传入参数
public class CUSEventArgs : EventArgs
{
public string msg { get; set; }
}
//事件类型
public class Publish
{
public event EventHandler publishHandler;
public void Raise()
{
publishHandler.Invoke(this, null);
}
public event EventHandler<CUSEventArgs> publishHandler_cus;
public void Raise_cus(string message)
{
publishHandler_cus.Invoke(this, new CUSEventArgs { msg = message });
}
}
EventHandler为内置的事件委托,此默认是包含sender和EventArgs,通过泛型可以修改EventArgs的类型,上面例子是通过CUSEventArgs 继承添加了msg参数。
两者区别
| 特性 | 委托(Delegate) | 事件(Event) |
|---|---|---|
| 访问权限 | 外部可直接调用、覆盖 | 外部仅能订阅 / 取消订阅 |
| 本质 | 引用类型(函数指针) | 委托的封装(特殊语法) |
| 适用场景 | 灵活的方法封装、回调 | 发布 - 订阅模式、解耦组件 |
| 多播支持 | 支持(+=/-=) | 支持(底层依赖委托多播) |
补充说明
- 委托的"直接调用"特性使其灵活性更高,但缺乏访问管控,外部代码可随意调用或覆盖委托指向的方法;
- 事件是委托的封装形式,仅对外暴露订阅(+=)和取消订阅(-=)操作,避免了委托被外部滥用,是.NET中实现发布-订阅模式的核心语法糖;
- 事件的多播能力本质上依赖委托的多播机制,二者底层逻辑一致,仅访问权限和使用场景有明确区分。