c#的委托

1111
示例:使用委托实现可插拔的行为
假设你有一个需要不同策略的排序方法,你可以通过委托将排序算法传递给方法,从而避免修改 Sort 方法的实现。

委托的声明既可以在命名空间也可以在类中

using System;

public delegate bool CompareDelegate(int x, int y);

public class Sorter
{
    public static void Sort(int[] array, CompareDelegate compare)
    {
        for (int i = 0; i < array.Length; i++)
        {
            for (int j = i + 1; j < array.Length; j++)
            {
                if (compare(array[i], array[j]))
                {
                    int temp = array[i];
                    array[i] = array[j];
                    array[j] = temp;
                }
            }
        }
    }
}

public class Program
{
    // 升序比较方法
    public static bool AscendingCompare(int x, int y) => x > y;

    // 降序比较方法
    public static bool DescendingCompare(int x, int y) => x < y;

    public static void Main()
    {
        int[] numbers = { 5, 3, 8, 1, 2 };
        
        // 使用委托传递排序算法
        Sorter.Sort(numbers, AscendingCompare);
        Console.WriteLine("Ascending: " + string.Join(", ", numbers));
        
        Sorter.Sort(numbers, DescendingCompare);
        Console.WriteLine("Descending: " + string.Join(", ", numbers));
    }
}
2. 实现事件和回调机制
委托是实现 事件 和 回调函数 的核心机制。特别是在用户界面开发中,事件处理和回调非常常见,而委托提供了一种灵活的方式来处理这些场景。

事件:委托是 C# 中实现事件的基础。通过委托,事件发布者可以通知多个事件订阅者(监听者)执行特定的处理逻辑。
回调函数:委托可以用来实现回调函数机制,即在某个操作完成后,由委托指定的方法来执行后续逻辑。
示例:事件处理
using System;

public delegate void Notify();  // 定义委托类型

public class Process
{
    public event Notify ProcessCompleted;  // 使用委托声明事件

    public void StartProcess()
    {
        Console.WriteLine("Processing...");
        // 处理完毕后触发事件
        OnProcessCompleted();
    }

    protected virtual void OnProcessCompleted()
    {
        ProcessCompleted?.Invoke();  // 触发事件
    }
}

public class Program
{
    public static void Main()
    {
        Process process = new Process();
        
        // 订阅事件
        process.ProcessCompleted += () => Console.WriteLine("Process Completed!");

        process.StartProcess();  // 启动进程,事件将会被触发
    }
}

2.例子代码

 

using System;

 

// 1. 定义委托
public delegate void MyEventHandler(string message);

 

public class EventPublisher
{
// 2. 定义事件
public event MyEventHandler MyEvent;

 

// 3. 触发事件
public void PublishEvent()
{
if (MyEvent != null)
{
MyEvent("事件已触发!");
}
}
}

 

public class EventSubscriber
{
public void OnMyEvent(string message)
{
Console.WriteLine(message);
}
}

 

public class Program
{
public static void Main()
{
EventPublisher publisher = new EventPublisher();
EventSubscriber subscriber = new EventSubscriber();

 

// 4. 订阅事件
publisher.MyEvent += subscriber.OnMyEvent;

 

// 触发事件
publisher.PublishEvent();
}
}

 

3. 支持多播委托(Multicast Delegates)
C# 的委托可以指向多个方法,这称为 多播委托。当你调用一个多播委托时,它会按顺序依次执行所有指向的方法。多播委托非常适合需要同时处理多个操作的场景,例如事件通知、日志记录等。

示例:多播委托

using System;

public delegate void Notify();  // 定义委托类型

public class Process
{
    public event Notify ProcessCompleted;  // 使用委托声明事件

    public void StartProcess()
    {
        Console.WriteLine("Processing...");
        // 处理完毕后触发事件
        OnProcessCompleted();
    }

    protected virtual void OnProcessCompleted()
    {
        ProcessCompleted?.Invoke();  // 触发事件
    }
}

public class Program
{
    public static void Main()
    {
        Process process = new Process();
        
        // 订阅多个方法
        process.ProcessCompleted += () => Console.WriteLine("Step 1 Completed!");
        process.ProcessCompleted += () => Console.WriteLine("Step 2 Completed!");

        process.StartProcess();  // 启动进程,事件将会被触发
    }
}
4. 支持回调和异步编程
委托特别适用于异步编程,尤其是回调函数和线程执行。当你执行一个异步操作时,可以传递一个委托作为回调,异步操作完成后通过这个委托来通知主线程或执行后续逻辑。

示例:使用委托进行异步回调

using System;
using System.Threading;

public delegate void CallbackDelegate(string result);  // 定义回调委托

public class Program
{
    public static void Main()
    {
        // 执行异步操作
        StartAsyncOperation(CallbackMethod);

        Console.WriteLine("Main thread is free to do other tasks...");
    }

    // 模拟异步操作
    public static void StartAsyncOperation(CallbackDelegate callback)
    {
        // 创建新线程模拟长时间运行的任务
        new Thread(() =>
        {
            Thread.Sleep(3000);  // 模拟耗时操作
            callback("Operation completed!");  // 操作完成后调用回调
        }).Start();
    }

    // 回调方法
    public static void CallbackMethod(string result)
    {
        Console.WriteLine(result);  // 输出回调结果
    }
}
5. 支持 LINQ 和函数式编程风格
委托与 LINQ(语言集成查询)结合使用时,能极大地提高代码的简洁性和可读性。通过使用委托,你可以编写更灵活、更易于扩展的代码,支持函数式编程风格。

示例:使用 Lambda 表达式和委托

using System;
using System.Linq;

public class Program
{
    public static void Main()
    {
        // 使用委托和 Lambda 表达式进行筛选
        Func<int, bool> isEven = x => x % 2 == 0;
        
        int[] numbers = { 1, 2, 3, 4, 5, 6 };
        
        var evenNumbers = numbers.Where(isEven).ToList();

        Console.WriteLine("Even numbers: " + string.Join(", ", evenNumbers));
    }
}

总结:使用委托的好处

  • 解耦:委托让方法调用者和方法实现者之间解耦,便于扩展和维护。
  • 事件和回调机制:委托是事件和回调的核心,使得异步编程、事件处理更加简洁和高效。
  • 多播委托:支持多播,允许一个委托调用多个方法,简化了多个方法的调用过程。
  • 支持异步编程:委托在异步回调、线程池等异步编程中具有重要作用。
  • 支持函数式编程:通过委托和 Lambda 表达式,可以更方便地实现函数式编程风格。



222
posted @ 2024-12-01 00:05  爱晒太阳的懒猫。。  阅读(18)  评论(0)    收藏  举报