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();
    }
}
相关推荐
m0_7487080516 分钟前
C++中的观察者模式实战
开发语言·c++·算法
qq_5375626728 分钟前
跨语言调用C++接口
开发语言·c++·算法
wjs202439 分钟前
DOM CDATA
开发语言
Tingjct40 分钟前
【初阶数据结构-二叉树】
c语言·开发语言·数据结构·算法
猷咪1 小时前
C++基础
开发语言·c++
IT·小灰灰1 小时前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧1 小时前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q1 小时前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳01 小时前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾1 小时前
php 对接deepseek
android·开发语言·php