委托
通俗的解释
1.方法指针的容器,就是一个能存放符合某种格式(方法签名)方法指针的清单。
2.委托是一个类
创建委托
namespace ConsoleApplication3 { //定义一个委托类 方法签名无返回值、无参 public delegate void DgSayHi(); }
调用委托
static void Main(string[] args) { Program program = new Program(); program.Test(); } public void Test() { //创建委托对象 DgSayHi dgSayHi = new DgSayHi(SayHiCn); //向委托对象中添加一个方法 dgSayHi += SayHiJp; //从委托对象中移除一个方法 dgSayHi -= SayHiCn; //调用委托 dgSayHi(); } void SayHiCn() { Console.WriteLine("你好"); } void SayHiJp() { Console.WriteLine("哦哈哟"); } }
图形描述
委托可以把一个方法作为参数进行传递
namespace ConsoleApplication3 { /// <summary> /// 定义一个泛型委托 /// </summary> /// <typeparam name="T">泛型参数</typeparam> /// <param name="t1">参数</param> /// <param name="t2">参数</param> /// <returns></returns> public delegate int DgCompare<T>(T t1, T t2); }
使用泛型委托
public void TestCompare() { int[] arr = { 1, 5, 2, 6, 1 }; Person[] person = { new Person(){ Age=21, Name="张苏纳"}, new Person(){ Age=50, Name="王五"}, new Person(){ Age=60, Name="老王"}, new Person(){ Age=40, Name="赵六"}, }; int max1 = GetMax<int>(arr, Compare); Person max2 = GetMax<Person>(person, Compare); Console.WriteLine(max1); Console.WriteLine(max2.Age.ToString(), max2.Name.ToString()); Console.ReadKey(); } public T GetMax<T>(T[] arr, DgCompare<T> dgCompare) { T max = arr[0]; for (int i = 0; i < arr.Length; i++) { if (dgCompare(arr[i], max) == 1) { max = arr[i]; } } return max; } int Compare(int x, int y) { return x > y ? 1 : 0; } int Compare(Person p1, Person p2) { return p1.Age > p2.Age ? 1 : 0; }
上面的方法可以使用匿名方法代替
public void TestCompare() { int[] arr = { 1, 5, 2, 6, 1 }; Person[] person = { new Person(){ Age=21, Name="张苏纳"}, new Person(){ Age=50, Name="王五"}, new Person(){ Age=60, Name="老王"}, new Person(){ Age=40, Name="赵六"}, }; int max1 = GetMax<int>(arr, delegate(int x, int y) { return x > y ? 1 : 0; }); Person max2 = GetMax<Person>(person, delegate(Person p1, Person p2) { return p1.Age > p2.Age ? 1 : 0; }); Console.WriteLine(max1); Console.WriteLine(max2.Age.ToString(), max2.Name.ToString()); Console.ReadKey(); }
委托源码分析
1.delegate 编译后会变成一个class,继承于MulticastDelegate(多播委托)
//向委托对象中添加一个方法
dgSayHi += SayHiJp;
//从委托对象中移除一个方法
dgSayHi -= SayHiCn;
查看对象的引用发生了地址的改变,产生了新的委托对象