1.委托:相当于函数指针,本质上是一个类,可以实例化,类内部存在指向方法的字段属性。
至于为什么使用委托,我个人认为它提高了程序的扩展性,在程序更新的时候,不需要大幅度修改程序内部的主要逻辑,只需要在原有的基础上进行扩展。
委托:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DelegateTest
{
internal class Program
{
//委托:将方法作为参数传递,而且方法的参数列表和返回值要与委托类型一致
//无参无返回值的委托
public delegate void DelegateTest();
//有参无返回值的委托
public delegate void DelegateTest2(int num,string str);
//有参有返回值的委托
public delegate int DelegateTest3(int num);
static void Main(string[] args)
{
//DelegateTest dt = new DelegateTest(Test); //函数传递的一种方式
DelegateTest dt = Test;//函数传递
dt();
DelegateTest2 dt2 = new DelegateTest2(Test2);
dt2(80,"张三");
DelegateTest3 dt3 = Test3;
int num = dt3(101);
Console.WriteLine(num);
}
public static void Test()
{
Console.WriteLine("DelegateTest");
}
public static void Test2(int num,string str)
{
Console.WriteLine($"{str}:{num}");
}
public static int Test3(int num)
{
Console.WriteLine(num);
return num;
}
}
}
多播委托:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DelegateTest
{
internal class Program
{
//多播委托:可以合并或移除多个委托对象,多播委托被调用时,它所合并的方法组或方法列表都会被调用,而且只有相同类型的委托对象才能合并
public delegate void DelegateTest();
static void Main(string[] args)
{
DelegateTest dt = Test;//函数传递
dt += Test2;//合并
DelegateTest dt2 = Test3;
dt += dt2;//合并
dt();
dt -= Test2;//移除
dt();
}
public static void Test()
{
Console.WriteLine("Test");
}
public static void Test2()
{
Console.WriteLine("Test2");
}
public static void Test3()
{
Console.WriteLine("Test3");
}
}
}
匿名委托:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DelegateTest
{
internal class Program
{
delegate void DelegateTest();
static void Main(string[] args)
{
//匿名委托
DelegateTest dt = delegate () { Console.WriteLine("匿名委托"); };
//Lambda表达式的写法
DelegateTest dt2 = () => Console.WriteLine("Lambda");
dt += Show;
dt();
dt += dt2;
dt();
}
static void Show()
{
Console.WriteLine("Show");
}
}
}
2.事件:相当于保存委托的数组,它是基于委托的。事件是一种特殊的委托,通过事件可以注册、取消多个多个委托和方法。算是完成用户操作所需要的委托和方法的集合。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DelegateTest
{
internal class Program
{
public delegate void DelegateTest();
//定义事件:事件是一个特殊的委托,事件可以作为变量拿到类之外去使用,但是发布必须在定义类里面实现
public static event DelegateTest EventDT;
static void Main(string[] args)
{
Student student = new Student();
student.GetInfo();//驱动方法内的事件进行注册
EventDT();//事件发布
}
}
class Student
{
private string name;
private int age;
//访问器
public string Name
{
set { name = value; }
get { return name; }
}
public int Age
{
get => age; set => age = value;
}
public void ShowInfo()
{
Console.WriteLine("张三:18");
}
public void ShowInfo2()
{
Console.WriteLine("李四:19");
}
public void GetInfo()
{
Program.DelegateTest dt = ShowInfo2;
Program.EventDT += ShowInfo;//注册方法
Program.EventDT += dt;//注册委托
}
}
}
3.委托与事件的区别:
(1)委托在类内类外都可以声明。事件只能在类内声明。
(2)委托和事件都可以在类内类外注册和注销方法,但是事件只能在类内调用,而委托可以在类内类外调用,使用事件可以提高调用的安全性,防止事件的调用权限被别人随便使用
(3)委托特别用于实现事件和回调方法。C#中使用事件实现线程间的通信,就像一个对外的接口
参考:
https://www.runoob.com/csharp/csharp-delegate.html
https://www.runoob.com/csharp/csharp-event.html
https://blog.csdn.net/shanniuliqingming/article/details/119547799?spm=1001.2014.3001.5506
结语:合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。