自定义委托
本章主要记录委托的语法及使用,以及 匿名方法 和 Lambda表达式 在委托中的运用。
【参考文章】《c# 图解教程》(第五版)
委托
委托是持有一个或多个方法的对象。与对象的区别是,可以执行委托。

如何使用委托
- 声明委托类型
//关键字:delegate
//返回类型:void
//委托类型名称:MyDel
//参数:int x
delegate void MyDel(int x);
- 创建委托对象
//委托类型:MyDel
//变量:delVar
MyDel delVar, dVar;
- 给委托赋值:由于委托是引用类型,可以通过给它赋值来改变包含在委托变量中的引用。旧的委托对象会被垃圾回收器回收。
//方式一:
//实例方法:myInstObj.MyM1
delVar = new MyDel(myInstObj.MyM1);
//静态方法:SClass.OtherM2
dVar = new MyDel(SClass.OtherM2);
//方式二:
delVar = myInstObj.MyM1;//创建委托对象并赋值
dVar = SClass.OtherM2;
delVar = SClass.OtherM2; //创建新的委托对象并赋值
- 组合委托:通过额外的运算符来创建一个新的委托。委托是恒定的。
MyDel delA = myInstObj.MyM1; //未改变
MyDel delB = SClass.OtherM2; //未改变
MyDel delC = delA + delB; //具有组合调用列表的新委托
//内存会为delC分配一块新区域,调用列表有新的myInstObj.MyM1、 SClass.OtherM2。
- 为委托添加方法:在执行 += 操作时,实际发生的时创建一个新的委托,其调用列表是左边的委托+右边方法的组合。然后将这个新的委托赋值给delVar。
- 从委托移除方法:若调用列表中的方法有多个实例,执行 -= 运算符将从列表最后开始搜索,并且移除第一个与方法匹配的实例。
MyDel delVar = inst.MyM1; //创建并初始化
delVar += SC1.m3; //在调用列表的底部增加方法
delVar += X.Act; //继续增加方法,所以目前delVar的调用列表里有3个方法
delVar -= SC1.m3; //从委托中移除方法,所以目前delVar的调用列表里有2个方法:inst.MyM1,X.Act
- 调用委托:调用空委托会抛出异常。可以通过检查委托是否等于null判断,如果调用列表为空,则委托为null。
MyDel delVar = inst.MyM1;
delVar += SC1.m3;
delVar += X.Act;
//方式1:像调用方法一样调用委托
if (null != delVar)
{
delVar(55); //调用委托
}
//方式2:使用委托的Invoke方法
delVar?.Invoke(65); //使用Invoke和空条件运算符
无参+无返 委托demo
//定义一个没有返回值,没有参数的委托类型
delegate void PrintFunction();
class Test
{
public void Print1()
{
Console.WriteLine("Print1 -- instance");
}
public static void Print2()
{
Console.WriteLine("Print2 -- static");
}
}
class DelegateTestDemo
{
static void Main()
{
Test t = new Test(); //创建一个测试类实例
PrintFunction pf; //创建一个空委托
pf = t.Print1; //实例化并初始化该委托
//给委托增加3个另外的方法
pf += Test.Print2;
pf += t.Print1;
pf += Test.Print2; //目前委托含有4个方法
if (null != pf) //确认委托有方法
{
pf(); //调用委托
}
else {
Console.WriteLine("Delegate is empty");
}
}
}
输出结果:
Print1 -- instance
Print2 -- static
Print1 -- instance
Print2 -- static
无参+有返 委托demo
//定义一个有返回值,没有参数的委托类型
delegate int MyDel();
class MyClass
{
int intValue = 5;
public int Add2()
{
intValue += 2;
return intValue;
}
public int Add3()
{
intValue += 3;
return intValue;
}
}
class DelegateTestDemo
{
static void Main()
{
MyClass mc = new MyClass();
MyDel mDel = mc.Add2; //创建并初始化该委托
//给委托增加2个方法
mDel += mc.Add3;
mDel += mc.Add2;
Console.WriteLine($"Value: {mDel()}");
}
}
输出结果:
Value: 12
有参+无返 委托demo
//定义一个无返回值,有参数的委托类型
delegate void MyDel(ref int x);
class MyClass
{
public void Add2(ref int x)
{
x += 2;
}
public void Add3(ref int x)
{
x += 3;
}
}
class DelegateTestDemo
{
static void Main()
{
MyClass mc = new MyClass();
MyDel mDel = mc.Add2; //创建并初始化该委托
//给委托增加2个方法
mDel += mc.Add3;
mDel += mc.Add2;
int x = 5;
mDel(ref x);
Console.WriteLine($"Value: { x }");
}
}
输出结果:
Value: 12
有参+有返 委托demo
class DelegateTestDemo
{
//定义一个有返回值,有参数的委托类型
delegate int OtherDel(int x);
public static int Add20(int x)
{
return x + 20;
}
static void Main()
{
OtherDel oDel = Add20; //创建并初始化该委托
Console.WriteLine("{0}",oDel(5));
Console.WriteLine("{0}", oDel(6));
}
}
输出结果:
25
26

浙公网安备 33010602011771号