委托概述
委托具有以下特点:
-
委托类似于 C++ 函数指针,但它们是类型安全的。
-
委托允许将方法作为参数进行传递。
-
委托可用于定义回调方法。
-
委托可以链接在一起;例如,可以对一个事件调用多个方法。
-
方法不必与委托签名完全匹配。
在以下情况下,请使用委托:
-
当使用事件设计模式时。
-
当封装静态方法可取时。
-
当调用方不需要访问实现该方法的对象中的其他属性、方法或接口时。
-
需要方便的组合。
-
当类可能需要该方法的多个实现时。
在以下情况下,请使用接口:
-
当存在一组可能被调用的相关方法时。
-
当类只需要方法的单个实现时。
-
当使用接口的类想要将该接口强制转换为其他接口或类类型时。
-
当正在实现的方法链接到类的类型或标识时:例如比较方法。
eg:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplicationdelegate
{
class Program
{
public delegate void MyDelegate(string str);
static void Main(string[] args)
{
MyDelegate dFun = new MyDelegate(Fun1);
dFun("D1"); // M1
// 创建一个委托实例,封装C类的静态方法M1
MyDelegate d1 = new MyDelegate(C.M1);
d1("D1"); // M1
// 创建一个委托实例,封装C类的静态方法M2
MyDelegate d2 = new MyDelegate(C.M2);
d2("D2"); // M2
// 创建一个委托实例,封装C类的实例方法M3
MyDelegate d3 = new MyDelegate(new C().M3);
d3("D3"); // M3
// 从一个委托d3创建一个委托实例
MyDelegate d4 = new MyDelegate(d3);
d4("D4"); // M3
// 组合两个委托
MyDelegate d5 = d1 + d2;
d5 += d3;
d5("D5"); // M1,M2,M3
// 从组合委托中删除d3
MyDelegate d6 = d5 - d3;
d6("D6"); // M1,M2
d6 -= d3; // 虽然d6调用列表中已经没有d3了,但这样只是不可能的移除没有错误发生
d6("D6"); // M1,M2
d6 -= d6;
//d6("D6"); 此时d6的调用列表为空,d6为null,所以引发System.NullReferenceException
MyDelegate d7 = new MyDelegate(C1.P1);//静态与非静态的区别
d7("D7"); // C1.P1
MyDelegate d8 = new MyDelegate(new C2().P1);
d8("D8"); // C2.P1
Console.ReadKey();
}
public static void Fun1(string str)
{
Console.WriteLine("From:fun1: {0}", str);
}
}//program
public delegate void MyDelegate(string str);
public class C
{
public static void M1(string str)
{
Console.WriteLine("From:C.M1: {0}", str);
}
public static void M2(string str)
{
Console.WriteLine("From:C.M2: {0}", str);
}
public void M3(string str)
{
Console.WriteLine("From:C.M3: {0}", str);
}
}
public class C1
{
public static void P1(string str)
{
Console.WriteLine("From:C1.P1: {0}", str);
}
}
public class C2
{
public void P1(string str)
{
Console.WriteLine("From:C2.P1: {0}", str);
}
}
}