C#泛型委托讲解

1. 泛型(Generics)

泛型允许编写类型安全且可重用的代码,避免装箱拆箱操作,提高性能。

泛型类

csharp 复制代码
// 定义泛型类
public class GenericList<T>
{
    private T[] items;
    private int count;
    
    public GenericList(int capacity)
    {
        items = new T[capacity];
    }
    
    public void Add(T item)
    {
        if (count < items.Length)
            items[count++] = item;
    }
    
    public T Get(int index)
    {
        if (index >= 0 && index < count)
            return items[index];
        throw new IndexOutOfRangeException();
    }
}

// 使用
var intList = new GenericList<int>(10);
var stringList = new GenericList<string>(10);

泛型方法

csharp 复制代码
public class Utility
{
    // 泛型方法
    public static void Swap<T>(ref T a, ref T b)
    {
        T temp = a;
        a = b;
        b = temp;
    }
    
    // 带约束的泛型方法
    public static T Max<T>(T a, T b) where T : IComparable<T>
    {
        return a.CompareTo(b) > 0 ? a : b;
    }
}

泛型约束

csharp 复制代码
// 多种约束类型
public class Repository<T> where T : class, IEntity, new()
{
    public T Create()
    {
        return new T();
    }
}

// 接口约束
public interface IEntity
{
    int Id { get; set; }
}

// 使用示例
public class Product : IEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
}

2. 委托(Delegates)

委托是类型安全的函数指针,可以引用静态或实例方法。

基本委托

csharp 复制代码
// 声明委托类型
public delegate void MyDelegate(string message);
public delegate int Calculator(int a, int b);

public class DelegateExample
{
    // 匹配委托签名的方法
    public static void Method1(string msg)
    {
        Console.WriteLine($"Method1: {msg}");
    }
    
    public void Method2(string msg)
    {
        Console.WriteLine($"Method2: {msg}");
    }
    
    public static void Demo()
    {
        MyDelegate del = Method1;
        del += new DelegateExample().Method2;
        
        // 多播委托
        del("Hello");  // 调用所有方法
        
        // 委托作为参数
        ProcessData("Test", Method1);
    }
    
    static void ProcessData(string data, MyDelegate processor)
    {
        processor(data);
    }
}

内置委托类型

csharp 复制代码
public class BuiltInDelegates
{
    public static void Demo()
    {
        // Action:无返回值
        Action<string> print = Console.WriteLine;
        Action<int, int> printSum = (a, b) => Console.WriteLine(a + b);
        
        // Func:有返回值
        Func<int, int, int> add = (a, b) => a + b;
        Func<string, bool> isNullOrEmpty = string.IsNullOrEmpty;
        
        // Predicate:返回bool
        Predicate<int> isEven = x => x % 2 == 0;
        
        // 使用示例
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
        var evenNumbers = numbers.FindAll(isEven);
    }
}

3. 事件(Events)

事件是特殊的多播委托,提供了发布-订阅模式。

标准事件模式

csharp 复制代码
// 事件参数类
public class StockPriceChangedEventArgs : EventArgs
{
    public string Symbol { get; set; }
    public decimal OldPrice { get; set; }
    public decimal NewPrice { get; set; }
}

// 发布者
public class Stock
{
    private string symbol;
    private decimal price;
    
    // 声明事件
    public event EventHandler<StockPriceChangedEventArgs> PriceChanged;
    
    public Stock(string symbol, decimal price)
    {
        this.symbol = symbol;
        this.price = price;
    }
    
    public decimal Price
    {
        get { return price; }
        set
        {
            if (price != value)
            {
                decimal oldPrice = price;
                price = value;
                OnPriceChanged(oldPrice, value);
            }
        }
    }
    
    // 触发事件的方法
    protected virtual void OnPriceChanged(decimal oldPrice, decimal newPrice)
    {
        PriceChanged?.Invoke(this, new StockPriceChangedEventArgs
        {
            Symbol = symbol,
            OldPrice = oldPrice,
            NewPrice = newPrice
        });
    }
}

// 订阅者
public class StockMonitor
{
    public void Subscribe(Stock stock)
    {
        stock.PriceChanged += Stock_PriceChanged;
    }
    
    private void Stock_PriceChanged(object sender, StockPriceChangedEventArgs e)
    {
        Console.WriteLine($"Stock {e.Symbol}: {e.OldPrice} -> {e.NewPrice}");
    }
}

4. 类之间的通信

接口通信

csharp 复制代码
public interface IMessageService
{
    void SendMessage(string message);
}

public class EmailService : IMessageService
{
    public void SendMessage(string message)
    {
        Console.WriteLine($"Email: {message}");
    }
}

public class NotificationManager
{
    private IMessageService messageService;
    
    public NotificationManager(IMessageService service)
    {
        messageService = service;
    }
    
    public void Notify(string message)
    {
        messageService.SendMessage(message);
    }
}

事件总线模式

csharp 复制代码
public class EventBus
{
    private static EventBus instance;
    private Dictionary<Type, List<Delegate>> subscribers = new Dictionary<Type, List<Delegate>>();
    
    public static EventBus Instance
    {
        get { return instance ?? (instance = new EventBus()); }
    }
    
    public void Subscribe<T>(Action<T> handler)
    {
        var type = typeof(T);
        if (!subscribers.ContainsKey(type))
            subscribers[type] = new List<Delegate>();
        
        subscribers[type].Add(handler);
    }
    
    public void Publish<T>(T eventData)
    {
        var type = typeof(T);
        if (subscribers.ContainsKey(type))
        {
            foreach (var handler in subscribers[type])
            {
                ((Action<T>)handler)(eventData);
            }
        }
    }
}

// 使用示例
public class OrderCreatedEvent
{
    public int OrderId { get; set; }
    public decimal Amount { get; set; }
}

// 发布
EventBus.Instance.Publish(new OrderCreatedEvent { OrderId = 1, Amount = 100 });

5. UI线程和后台线程通信

Windows Forms中的线程通信

csharp 复制代码
public partial class MainForm : Form
{
    // 使用Control.Invoke
    private void BackgroundWork()
    {
        Thread.Sleep(2000); // 模拟耗时操作
        
        // 更新UI必须在UI线程
        this.Invoke(new Action(() =>
        {
            label1.Text = "工作完成";
            progressBar1.Value = 100;
        }));
    }
    
    // 使用BackgroundWorker
    private void InitializeBackgroundWorker()
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerReportsProgress = true;
        worker.WorkerSupportsCancellation = true;
        
        worker.DoWork += (sender, e) =>
        {
            for (int i = 0; i <= 100; i++)
            {
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
                
                Thread.Sleep(50);
                worker.ReportProgress(i);
            }
        };
        
        worker.ProgressChanged += (sender, e) =>
        {
            progressBar1.Value = e.ProgressPercentage;
            label1.Text = $"进度: {e.ProgressPercentage}%";
        };
        
        worker.RunWorkerCompleted += (sender, e) =>
        {
            if (e.Cancelled)
                label1.Text = "已取消";
            else
                label1.Text = "完成";
        };
        
        worker.RunWorkerAsync();
    }
}

WPF中的Dispatcher

csharp 复制代码
public partial class MainWindow : Window
{
    private void BackgroundOperation()
    {
        Task.Run(() =>
        {
            // 后台操作
            string result = PerformCalculation();
            
            // 更新UI
            Dispatcher.Invoke(() =>
            {
                ResultTextBlock.Text = result;
            });
            
            // 或使用BeginInvoke(异步)
            Dispatcher.BeginInvoke(new Action(() =>
            {
                StatusLabel.Content = "计算完成";
            }));
        });
    }
}

6. 多线程

Thread类

csharp 复制代码
public class ThreadingExample
{
    private static object lockObject = new object();
    private static int counter = 0;
    
    public static void BasicThreading()
    {
        Thread t1 = new Thread(WorkerMethod);
        Thread t2 = new Thread(() => Console.WriteLine("Lambda线程"));
        
        t1.Name = "Worker Thread";
        t1.IsBackground = true;
        t1.Start("参数");
        
        t2.Start();
        
        // 等待线程完成
        t1.Join();
        t2.Join();
    }
    
    static void WorkerMethod(object data)
    {
        Console.WriteLine($"线程 {Thread.CurrentThread.Name}: {data}");
        
        // 线程同步
        lock (lockObject)
        {
            counter++;
            Console.WriteLine($"Counter: {counter}");
        }
    }
}

ThreadPool

csharp 复制代码
public class ThreadPoolExample
{
    public static void Demo()
    {
        // 使用线程池
        ThreadPool.QueueUserWorkItem(WorkItem, "任务1");
        ThreadPool.QueueUserWorkItem(WorkItem, "任务2");
        
        // 设置线程池大小
        ThreadPool.SetMinThreads(4, 4);
        ThreadPool.SetMaxThreads(10, 10);
        
        // 使用ManualResetEvent进行同步
        ManualResetEvent mre = new ManualResetEvent(false);
        
        ThreadPool.QueueUserWorkItem((state) =>
        {
            Console.WriteLine("等待信号...");
            mre.WaitOne();
            Console.WriteLine("收到信号,继续执行");
        });
        
        Thread.Sleep(2000);
        mre.Set(); // 发送信号
    }
    
    static void WorkItem(object state)
    {
        Console.WriteLine($"线程池线程: {state}");
    }
}

Task并行库 (TPL)

csharp 复制代码
public class TaskExample
{
    public static async void TaskDemo()
    {
        // 创建和启动任务
        Task<int> task1 = Task.Run(() =>
        {
            Thread.Sleep(1000);
            return 42;
        });
        
        // 继续任务
        Task task2 = task1.ContinueWith(t =>
        {
            Console.WriteLine($"结果: {t.Result}");
        });
        
        // 并行执行多个任务
        Task[] tasks = new Task[3];
        for (int i = 0; i < 3; i++)
        {
            int index = i;
            tasks[i] = Task.Factory.StartNew(() =>
            {
                Console.WriteLine($"任务 {index} 在线程 {Thread.CurrentThread.ManagedThreadId}");
            });
        }
        
        Task.WaitAll(tasks);
        
        // 使用async/await
        int result = await CalculateAsync();
        Console.WriteLine($"异步结果: {result}");
    }
    
    static async Task<int> CalculateAsync()
    {
        await Task.Delay(1000);
        return 100;
    }
}

并发集合

csharp 复制代码
public class ConcurrentCollectionExample
{
    public static void Demo()
    {
        // 线程安全的集合
        ConcurrentDictionary<int, string> dict = new ConcurrentDictionary<int, string>();
        ConcurrentQueue<string> queue = new ConcurrentQueue<string>();
        ConcurrentBag<int> bag = new ConcurrentBag<int>();
        BlockingCollection<string> blocking = new BlockingCollection<string>();
        
        // 并行添加数据
        Parallel.For(0, 100, i =>
        {
            dict.TryAdd(i, $"Value{i}");
            queue.Enqueue($"Item{i}");
            bag.Add(i);
        });
        
        // 生产者-消费者模式
        Task producer = Task.Run(() =>
        {
            for (int i = 0; i < 10; i++)
            {
                blocking.Add($"Item{i}");
                Thread.Sleep(100);
            }
            blocking.CompleteAdding();
        });
        
        Task consumer = Task.Run(() =>
        {
            foreach (var item in blocking.GetConsumingEnumerable())
            {
                Console.WriteLine($"消费: {item}");
            }
        });
        
        Task.WaitAll(producer, consumer);
    }
}

7. 多进程

Process类

csharp 复制代码
public class ProcessExample
{
    public static void ProcessDemo()
    {
        // 启动新进程
        Process process = new Process();
        process.StartInfo.FileName = "notepad.exe";
        process.StartInfo.Arguments = "test.txt";
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.Start();
        
        // 等待进程退出
        process.WaitForExit();
        int exitCode = process.ExitCode;
        
        // 获取所有进程
        Process[] processes = Process.GetProcesses();
        foreach (var p in processes)
        {
            Console.WriteLine($"{p.ProcessName} - {p.Id}");
        }
    }
    
    // 进程间通信 - 命名管道
    public static void NamedPipeServer()
    {
        using (NamedPipeServerStream pipeServer = new NamedPipeServerStream("testpipe"))
        {
            Console.WriteLine("等待客户端连接...");
            pipeServer.WaitForConnection();
            
            using (StreamReader sr = new StreamReader(pipeServer))
            using (StreamWriter sw = new StreamWriter(pipeServer))
            {
                sw.AutoFlush = true;
                string message = sr.ReadLine();
                Console.WriteLine($"收到: {message}");
                sw.WriteLine("服务器响应");
            }
        }
    }
    
    public static void NamedPipeClient()
    {
        using (NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", "testpipe"))
        {
            pipeClient.Connect();
            
            using (StreamReader sr = new StreamReader(pipeClient))
            using (StreamWriter sw = new StreamWriter(pipeClient))
            {
                sw.AutoFlush = true;
                sw.WriteLine("客户端消息");
                string response = sr.ReadLine();
                Console.WriteLine($"收到响应: {response}");
            }
        }
    }
}

进程间通信 - 内存映射文件

csharp 复制代码
public class MemoryMappedFileExample
{
    public static void CreateMemoryMappedFile()
    {
        using (var mmf = MemoryMappedFile.CreateNew("SharedMemory", 10000))
        {
            using (var accessor = mmf.CreateViewAccessor())
            {
                accessor.Write(0, 42);
                accessor.Write(4, 3.14f);
                
                Console.WriteLine("数据已写入共享内存,按任意键退出...");
                Console.ReadKey();
            }
        }
    }
    
    public static void ReadMemoryMappedFile()
    {
        using (var mmf = MemoryMappedFile.OpenExisting("SharedMemory"))
        {
            using (var accessor = mmf.CreateViewAccessor())
            {
                int intValue = accessor.ReadInt32(0);
                float floatValue = accessor.ReadSingle(4);
                
                Console.WriteLine($"读取的值: {intValue}, {floatValue}");
            }
        }
    }
}

综合示例:生产者-消费者模式

csharp 复制代码
public class ProducerConsumerExample
{
    private readonly Queue<WorkItem> workQueue = new Queue<WorkItem>();
    private readonly object queueLock = new object();
    private readonly AutoResetEvent workAvailable = new AutoResetEvent(false);
    private readonly CancellationTokenSource cancellation = new CancellationTokenSource();
    
    public class WorkItem
    {
        public int Id { get; set; }
        public string Data { get; set; }
        public DateTime CreatedTime { get; set; }
    }
    
    // 生产者
    public void Producer()
    {
        int itemId = 0;
        while (!cancellation.Token.IsCancellationRequested)
        {
            var item = new WorkItem
            {
                Id = ++itemId,
                Data = $"工作项 {itemId}",
                CreatedTime = DateTime.Now
            };
            
            lock (queueLock)
            {
                workQueue.Enqueue(item);
                Console.WriteLine($"生产: {item.Data}");
            }
            
            workAvailable.Set(); // 通知消费者
            Thread.Sleep(1000); // 模拟生产延迟
        }
    }
    
    // 消费者
    public void Consumer(int consumerId)
    {
        while (!cancellation.Token.IsCancellationRequested)
        {
            workAvailable.WaitOne(); // 等待工作项
            
            WorkItem item = null;
            lock (queueLock)
            {
                if (workQueue.Count > 0)
                {
                    item = workQueue.Dequeue();
                }
            }
            
            if (item != null)
            {
                // 处理工作项
                Console.WriteLine($"消费者 {consumerId} 处理: {item.Data}");
                Thread.Sleep(2000); // 模拟处理时间
            }
        }
    }
    
    public void Start()
    {
        // 启动生产者
        Task.Factory.StartNew(Producer, TaskCreationOptions.LongRunning);
        
        // 启动多个消费者
        for (int i = 1; i <= 3; i++)
        {
            int consumerId = i;
            Task.Factory.StartNew(() => Consumer(consumerId), TaskCreationOptions.LongRunning);
        }
        
        Console.ReadKey();
        cancellation.Cancel();
    }
}
相关推荐
seabirdssss2 小时前
错误: 找不到或无法加载主类 原因: java.lang.ClassNotFoundException
java·开发语言
gnawkhhkwang2 小时前
io_getevents 和 io_pgetevents 系统调用及示例
linux·c语言·开发语言
喵手2 小时前
使用ASIWebPageRequest库编写Objective-C下载器程序
开发语言·macos·objective-c
君莫笑几人回3 小时前
关于记录一下“bug”,在做图片上传的时候出现的小问题
java·开发语言·spring boot
rockmelodies3 小时前
RSA 解密逻辑
开发语言·python
澡点睡觉4 小时前
golang的包和闭包
开发语言·后端·golang
Dxy12393102164 小时前
python创建一个excel文件
开发语言·python·excel
朝朝又沐沐5 小时前
算法竞赛阶段二-数据结构(40)数据结构栈的STL
开发语言·数据结构·c++·算法