C#委托的常见模式及应用举例
在C#编程中,委托是一种类型安全的函数指针,它允许将方法作为参数传递或赋值给变量。委托的灵活性和强大功能使得它在事件处理、异步编程、回调函数等场景中得到了广泛应用。下面将介绍C#中几种常见的委托模式,并通过具体例子来说明它们的应用。
1. 事件模式
事件模式是C#中最常见的委托应用之一。通过定义事件,类可以通知其他对象当某些特定事情发生时。事件通常使用委托类型来声明,并且只允许在定义它的类内部触发。
// 声明一个委托类型用于事件处理
public delegate void MyEventHandler(object sender, EventArgs e);
// 定义一个包含事件的类
public class MyClass
{
// 声明事件
public event MyEventHandler MyEvent;
// 保护方法,用于触发事件
protected virtual void OnMyEvent(EventArgs e)
{
MyEvent?.Invoke(this, e);
}
// 一个方法,当某些条件满足时触发事件
public void DoSomething()
{
// ... 执行一些操作 ...
OnMyEvent(EventArgs.Empty); // 触发事件
}
}
// 使用事件的客户端代码
class Program
{
static void Main(string[] args)
{
MyClass myObject = new MyClass();
myObject.MyEvent += new MyEventHandler(MyObject_MyEvent); // 订阅事件
myObject.DoSomething(); // 执行操作,触发事件
}
static void MyObject_MyEvent(object sender, EventArgs e)
{
Console.WriteLine("MyEvent was raised!"); // 事件处理逻辑
}
}
2. 回调模式
回调模式允许将一个方法作为参数传递给另一个方法,并在适当的时候调用它。这在异步操作、定时器回调等场景中非常有用。
// 声明一个委托用于回调
public delegate void Callback(string result);
// 一个执行异步操作并回调的类
public class AsyncOperation
{
public void Start(Callback callback)
{
// 模拟异步操作(例如,使用Task或Thread)
string result = "Operation completed";
callback?.Invoke(result); // 调用回调方法
}
}
// 使用回调的客户端代码
class Program
{
static void Main(string[] args)
{
AsyncOperation op = new AsyncOperation();
op.Start(OperationCompleted); // 开始异步操作并指定回调方法
}
static void OperationCompleted(string result)
{
Console.WriteLine(result); // 处理异步操作的结果
}
}
3. 多播委托
多播委托允许将一个委托变量关联到多个方法,当委托被调用时,所有关联的方法都会按顺序执行。
// 声明一个多播委托用于处理事件或回调
public delegate void MultiCastDelegate(string message);
class Program
{
static void Main(string[] args)
{
MultiCastDelegate mcd = MessageHandler1; // 关联第一个方法
mcd += MessageHandler2; // 关联第二个方法,形成多播委托
mcd("Hello, world!"); // 调用委托,两个方法都会被执行
}
static void MessageHandler1(string message)
{
Console.WriteLine("Handler 1: " + message);
}
static void MessageHandler2(string message)
{
Console.WriteLine("Handler 2: " + message);
}
}
class Program
{
static void Main(string[] args)
{
// 创建一个Action委托实例,它不接受任何参数且没有返回值
Action myAction = null;
// 使用+=运算符来添加多个方法或Lambda表达式到多播委托
myAction += () => Console.WriteLine("Lambda expression 1 executed.");
myAction += () => Console.WriteLine("Lambda expression 2 executed.");
myAction += MethodToInvoke; // 添加一个方法到多播委托
// 调用多播委托,所有添加的方法或Lambda表达式都会被执行
myAction();
// 也可以继续添加更多的方法或Lambda表达式到多播委托
myAction += () => Console.WriteLine("Another lambda expression executed.");
// 再次调用多播委托,新添加的方法或Lambda表达式也会被执行
myAction();
}
// 一个与Action委托签名匹配的方法
static void MethodToInvoke()
{
Console.WriteLine("MethodToInvoke executed.");
}
}
4.委托作为返回值
// 声明一个委托
public delegate string StringOperation(string input);
class Program
{
static void Main(string[] args)
{
// 创建一个返回委托的方法实例
StringOperation operation = GetOperation();
// 调用返回的委托
string result = operation("Hello, world!");
Console.WriteLine(result); // 输出: HELLO, WORLD!
}
// 一个方法,它返回一个委托实例,该实例指向ToUpper方法
static StringOperation GetOperation()
{
// 返回指向ToUpper方法的委托
return new StringOperation(string.ToUpper);
}
}
5.Lambda表达式和委托:
Lambda表达式提供了一种简洁的方式来创建匿名函数,这些函数可以直接赋值给委托变量。Lambda表达式使得委托的使用更加灵活和方便。
// 声明一个委托类型
public delegate int BinaryOp(int x, int y);
class Program
{
static void Main(string[] args)
{
// 使用Lambda表达式创建一个BinaryOp委托实例
BinaryOp add = (x, y) => x + y; // 调用委托实例
int sum = add(5, 3);
Console.WriteLine("Sum: " + sum); // 输出: Sum: 8
}
}