C#委托基础
C#中的委托
委托可以认为是持有一个或者多个方法的对象,委托可以认为是一个类型安全的、面向对象的C/C++函数指针。如下例程序:
namespace CSharpProject1;
delegate void MyDelegate(int value); // 声明委托类型(没有返回值的类型,使用delegate, value为委托参数)
class Program
{
static void PrintLow(int value)
{
Console.WriteLine($"{value} - Low Value");
}
static void PrintHigh(int value)
{
Console.WriteLine($"{value} - High Value");
}
static void Main(string[] args)
{
MyDelegate myDelegate; // 声明委托变量
// 创建随机数生成器
Random r = new Random();
int randomValue = r.Next(99);
// 创建一个包含PrintLow或者PrintHigh的委托对象并赋值给委托变量
myDelegate = (randomValue < 50) ? new MyDelegate(Program.PrintLow) : new MyDelegate(Program.PrintHigh);
// 执行委托传递参数
myDelegate.Invoke(randomValue);
}
}
委托和类一样,是一种用户定义类型,但类表示的是数据和方法的集合,二委托则持有一个或者多个方法。使用委托方法如下:
- 声明一个委托类型。委托声明看上去和方法声明相似,只是没有实现块。
- 使用该委托类型声明一个委托变量。
- 创建一个委托类型的对象,委托方法包含指向某个方法的引用,这个方法的签名和返回类型必须跟第一步中定义的委托类型一致。
- 在代码中可以像调用方法一样调用委托。
调用委托
- 可以通过两种方式调用委托。一种像是调用方法一样使用委托;另一种是使用委托的额Invoke方法。
- 在传递参数时,可以直接将参数放在花括号里。
- 在调用时委托不能为空(null),否则将引发异常,可以使用if语句来检查,也可以使用空条件运算符和Invoke方法。
- 如果一个方法在调用列表中多次出现,则在调用委托时,每次在列表中遇到该方法时都会调用它。
委托的示例
没有返回值和参数的委托
namespace CSharpProject1;
// 定义一个没有返回值和参数的委托
delegate void PrintFunction();
class Test
{
public void Print1()
{
Console.WriteLine("Print1 -- instance");
}
public static void Print2()
{
Console.WriteLine("Print2 -- static");
}
}
class Program
{
static void Main(string[] args)
{
Test t = new Test(); // 创建一个测试类实例
PrintFunction pf; // 创建一个空委托
pf = t.Print1; // 实例化并初始化委托
// 给委托增加3个另外的方法
pf += Test.Print2;
pf += t.Print1;
pf += Test.Print2;
// 现在委托有4个方法
if (pf != null) pf();//调用委托
else Console.WriteLine("Delegate is empty");
}
}
调用带返回值的委托
如果委托有返回值并且在调用列表中有一个以上的方法,会发生下面的情况。
- 调用列表中最后一个方法返回的值就是委托调用返回的值。
- 委托列表中所有其他方法的返回值都会忽略。
namespace CSharpProject1;
// 定义一个有返回值的委托
delegate int MyDelegate();
class MyClass
{
int value = 5;
public int Add2()
{
value += 2;
return value;
}
public int Add3()
{
value += 3;
return value;
}
}
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass();
MyDelegate md = mc.Add2;
md += mc.Add3;
Console.WriteLine($"value: {md()}");
}
}
调用带引用参数的委托
如果委托有引用参数,参数值会根据调用列表中的一个或者多个方法的返回值而改变。在调用委托列表中的下一个方法时,参数的新值(不是初始值)回传给下一个方法。例如:
namespace CSharpProject1;
// 定义一个没有回值带有参数的委托
delegate void MyDeleGate(ref int x);
class Program
{
public void Add2(ref int x)
{
x += 2;
}
public void Add3(ref int x)
{
x += 3;
}
static void Main(string[] args)
{
Program p = new Program();
MyDeleGate md = p.Add2;
md += p.Add3;
int x = 5;
md.Invoke(ref x);
Console.WriteLine($"value:{x}");
}
}
D:/RiderProjects/CSharpProject1/CSharpProject1/bin/Debug/net8.0/CSharpProject1.exe
value:10
Process finished with exit code 0.
匿名方法
匿名方法是在实例化时内联声明的方法。例如:
使用匿名方法:
namespace CSharpProject1;
class Program
{
delegate int OtherDelegate(int param);
static void Main(string[] args)
{
OtherDelegate del = delegate(int x)
{
return x + 20;
};
Console.WriteLine($"{del(5)}");
Console.WriteLine($"{del(6)}");
}
}
使用具体方法:
namespace CSharpProject1;
class Program
{
public static int Add20(int x)
{
return x + 20;
}
delegate int OtherDelegate(int param);
static void Main(string[] args)
{
OtherDelegate del = Add20;
Console.WriteLine($"{del.Invoke(5)}");
Console.WriteLine($"{del.Invoke(6)}");
}
}
D:/RiderProjects/CSharpProject1/CSharpProject1/bin/Debug/net8.0/CSharpProject1.exe
25
26
Process finished with exit code 0.
使用匿名方法
我们可以在如下地方使用匿名方法:
- 声明委托变量时作为初始化表达式。
- 组合委托时在赋值语句的右边。
- 为委托增加事件时在赋值语句的右边。
匿名方法的语法
delegate(int param) {语句块}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!