本章目标

通过本章学习,你将掌握: - 泛型的概念和优势 - 泛型类和泛型接口 - 泛型方法和泛型委托 - 泛型约束的使用 - 协变和逆变 - 泛型集合的使用 - 泛型的性能优势

1. 泛型基础

1.1 泛型的概念

泛型允许在定义类、接口、方法时使用类型参数,在使用时指定具体类型,提供类型安全和性能优势。

// 非泛型版本的问题
public class ObjectStack
{
    private object[] items;
    private int count;
    
    public ObjectStack(int capacity = 10)
    {
        items = new object[capacity];
        count = 0;
    }
    
    public void Push(object item)
    {
        if (count >= items.Length)
            throw new InvalidOperationException("栈已满");
        items[count++] = item;
    }
    
    public object Pop()
    {
        if (count == 0)
            throw new InvalidOperationException("栈为空");
        return items[--count];
    }
    
    public int Count => count;
}

// 泛型版本的优势
public class GenericStack<T>
{
    private T[] items;
    private int count;
    
    public GenericStack(int capacity = 10)
    {
        items = new T[capacity];
        count = 0;
    }
    
    public void Push(T item)
    {
        if (count >= items.Length)
        {
            // 自动扩容
            Array.Resize(ref items, items.Length * 2);
        }
        items[count++] = item;
    }
    
    public T Pop()
    {
        if (count == 0)
            throw new InvalidOperationException("栈为空");
        return items[--count];
    }
    
    public T Peek()
    {
        if (count == 0)
            throw new InvalidOperationException("栈为空");
        return items[count - 1];
    }
    
    public bool IsEmpty => count == 0;
    public int Count => count;
    public int Capacity => items.Length;
    
    // 泛型方法
    public bool Contains(T item)
    {
        for (int i = 0; i < count; i++)
        {
            if (EqualityComparer<T>.Default.Equals(items[i], item))
                return true;
        }
        return false;
    }
    
    public T[] ToArray()
    {
        T[] result = new T[count];
        Array.Copy(items, result, count);
        return result;
    }
    
    public void Clear()
    {
        // 对于引用类型,清除引用以便垃圾回收
        if (!typeof(T).IsValueType)
        {
            Array.Clear(items, 0, count);
        }
        count = 0;
    }
}

// 泛型使用示例
public class GenericBasicsDemo
{
    public static void DemonstrateGenericAdvantages()
    {
        Console.WriteLine("=== 泛型优势演示 ===");
        
        // 非泛型版本的问题
        Console.WriteLine("\n--- 非泛型版本的问题 ---");
        var objectStack = new ObjectStack();
        objectStack.Push(1);        // 装箱
        objectStack.Push("hello");  // 类型不安全
        objectStack.Push(3.14);     // 装箱
        
        // 需要类型转换,可能出现运行时错误
        try
        {
            int value1 = (int)objectStack.Pop(); // 拆箱
            Console.WriteLine($"弹出:{value1}");
            
            int value2 = (int)objectStack.Pop(); // 运行时错误!
            Console.WriteLine($"弹出:{value2}");
        }
        catch (InvalidCastException ex)
        {
            Console.WriteLine($"类型转换错误:{ex.Message}");
        }
        
        // 泛型版本的优势
        Console.WriteLine("\n--- 泛型版本的优势 ---");
        var intStack = new GenericStack<int>();
        intStack.Push(1);    // 无装箱
        intStack.Push(2);    // 类型安全
        intStack.Push(3);
        
        Console.WriteLine($"栈中元素数量:{intStack.Count}");
        Console.WriteLine($"栈容量:{intStack.Capacity}");
        Console.WriteLine($"栈顶元素:{intStack.Peek()}");
        
        while (!intStack.IsEmpty)
        {
            int value = intStack.Pop(); // 无需类型转换
            Console.WriteLine($"弹出:{value}");
        }
        
        // 字符串栈
        var stringStack = new GenericStack<string>();
        stringStack.Push("Hello");
        stringStack.Push("World");
        stringStack.Push("Generic");
        
        Console.WriteLine($"\n字符串栈包含'World':{stringStack.Contains("World")}");
        Console.WriteLine($"字符串栈内容:[{string.Join(", ", stringStack.ToArray())}]");
        
        // 自定义类型栈
        var personStack = new GenericStack<Person>();
        personStack.Push(new Person("张三", 25));
        personStack.Push(new Person("李四", 30));
        
        Console.WriteLine($"\n人员栈顶:{personStack.Peek()}");
    }
}

// 示例类
public class Person
{
    public string Name { get; }
    public int Age { get; }
    
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
    
    public override string ToString()
    {
        return $"{Name}({Age}岁)";
    }
    
    public override bool Equals(object obj)
    {
        return obj is Person person && Name == person.Name && Age == person.Age;
    }
    
    public override int GetHashCode()
    {
        return HashCode.Combine(Name, Age);
    }
}

1.2 泛型类和泛型接口

// 泛型接口
public interface IRepository<T> where T : class
{
    void Add(T entity);
    T GetById(int id);
    IEnumerable<T> GetAll();
    void Update(T entity);
    void Delete(int id);
    bool Exists(int id);
}

// 泛型基类
public abstract class BaseEntity
{
    public int Id { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime UpdatedAt { get; set; }
    
    protected BaseEntity()
    {
        CreatedAt = DateTime.Now;
        UpdatedAt = DateTime.Now;
    }
}

// 具体实体类
public class Product : BaseEntity
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    public string Category { get; set; }
    public int Stock { get; set; }
    
    public Product() { }
    
    public Product(string name, decimal price, string category, int stock)
    {
        Name = name;
        Price = price;
        Category = category;
        Stock = stock;
    }
    
    public override string ToString()
    {
        return $"{Name} - ¥{Price} ({Category}) [库存:{Stock}]";
    }
}

public class Customer : BaseEntity
{
    public string Name { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public string Address { get; set; }
    
    public Customer() { }
    
    public Customer(string name, string email, string phone, string address)
    {
        Name = name;
        Email = email;
        Phone = phone;
        Address = address;
    }
    
    public override string ToString()
    {
        return $"{Name} ({Email}) - {Phone}";
    }
}

// 泛型仓储实现
public class MemoryRepository<T> : IRepository<T> where T : BaseEntity
{
    private readonly Dictionary<int, T> entities;
    private int nextId;
    
    public MemoryRepository()
    {
        entities = new Dictionary<int, T>();
        nextId = 1;
    }
    
    public void Add(T entity)
    {
        if (entity == null)
            throw new ArgumentNullException(nameof(entity));
            
        entity.Id = nextId++;
        entity.CreatedAt = DateTime.Now;
        entity.UpdatedAt = DateTime.Now;
        entities[entity.Id] = entity;
        
        Console.WriteLine($"添加实体:{entity.GetType().Name} (ID: {entity.Id})");
    }
    
    public T GetById(int id)
    {
        entities.TryGetValue(id, out T entity);
        return entity;
    }
    
    public IEnumerable<T> GetAll()
    {
        return entities.Values.OrderBy(e => e.Id);
    }
    
    public void Update(T entity)
    {
        if (entity == null)
            throw new ArgumentNullException(nameof(entity));
            
        if (!entities.ContainsKey(entity.Id))
            throw new ArgumentException($"实体不存在:ID {entity.Id}");
            
        entity.UpdatedAt = DateTime.Now;
        entities[entity.Id] = entity;
        
        Console.WriteLine($"更新实体:{entity.GetType().Name} (ID: {entity.Id})");
    }
    
    public void Delete(int id)
    {
        if (entities.Remove(id))
        {
            Console.WriteLine($"删除实体:ID {id}");
        }
        else
        {
            throw new ArgumentException($"实体不存在:ID {id}");
        }
    }
    
    public bool Exists(int id)
    {
        return entities.ContainsKey(id);
    }
    
    public int Count => entities.Count;
    
    // 额外的泛型方法
    public IEnumerable<T> FindBy(Func<T, bool> predicate)
    {
        return entities.Values.Where(predicate);
    }
    
    public T FirstOrDefault(Func<T, bool> predicate)
    {
        return entities.Values.FirstOrDefault(predicate);
    }
}

// 泛型服务类
public class GenericService<T> where T : BaseEntity
{
    private readonly IRepository<T> repository;
    
    public GenericService(IRepository<T> repository)
    {
        this.repository = repository ?? throw new ArgumentNullException(nameof(repository));
    }
    
    public void CreateEntity(T entity)
    {
        ValidateEntity(entity);
        repository.Add(entity);
    }
    
    public T GetEntity(int id)
    {
        var entity = repository.GetById(id);
        if (entity == null)
            throw new ArgumentException($"实体不存在:ID {id}");
        return entity;
    }
    
    public IEnumerable<T> GetAllEntities()
    {
        return repository.GetAll();
    }
    
    public void UpdateEntity(T entity)
    {
        ValidateEntity(entity);
        repository.Update(entity);
    }
    
    public void DeleteEntity(int id)
    {
        repository.Delete(id);
    }
    
    public bool EntityExists(int id)
    {
        return repository.Exists(id);
    }
    
    protected virtual void ValidateEntity(T entity)
    {
        if (entity == null)
            throw new ArgumentNullException(nameof(entity));
    }
    
    // 泛型查询方法
    public IEnumerable<T> Search(Func<T, bool> criteria)
    {
        return repository.FindBy(criteria);
    }
    
    public T FindFirst(Func<T, bool> criteria)
    {
        return repository.FirstOrDefault(criteria);
    }
}

// 具体服务类
public class ProductService : GenericService<Product>
{
    public ProductService(IRepository<Product> repository) : base(repository) { }
    
    protected override void ValidateEntity(Product product)
    {
        base.ValidateEntity(product);
        
        if (string.IsNullOrWhiteSpace(product.Name))
            throw new ArgumentException("产品名称不能为空");
            
        if (product.Price <= 0)
            throw new ArgumentException("产品价格必须大于0");
            
        if (product.Stock < 0)
            throw new ArgumentException("库存不能为负数");
    }
    
    public IEnumerable<Product> GetProductsByCategory(string category)
    {
        return Search(p => p.Category.Equals(category, StringComparison.OrdinalIgnoreCase));
    }
    
    public IEnumerable<Product> GetProductsInPriceRange(decimal minPrice, decimal maxPrice)
    {
        return Search(p => p.Price >= minPrice && p.Price <= maxPrice);
    }
    
    public IEnumerable<Product> GetLowStockProducts(int threshold = 10)
    {
        return Search(p => p.Stock <= threshold);
    }
}

public class CustomerService : GenericService<Customer>
{
    public CustomerService(IRepository<Customer> repository) : base(repository) { }
    
    protected override void ValidateEntity(Customer customer)
    {
        base.ValidateEntity(customer);
        
        if (string.IsNullOrWhiteSpace(customer.Name))
            throw new ArgumentException("客户姓名不能为空");
            
        if (string.IsNullOrWhiteSpace(customer.Email) || !customer.Email.Contains("@"))
            throw new ArgumentException("邮箱格式无效");
    }
    
    public Customer GetCustomerByEmail(string email)
    {
        return FindFirst(c => c.Email.Equals(email, StringComparison.OrdinalIgnoreCase));
    }
    
    public IEnumerable<Customer> SearchCustomersByName(string namePattern)
    {
        return Search(c => c.Name.Contains(namePattern, StringComparison.OrdinalIgnoreCase));
    }
}

1.3 泛型类和接口使用示例

public class GenericClassDemo
{
    public static void DemonstrateGenericClasses()
    {
        Console.WriteLine("\n=== 泛型类和接口演示 ===");
        
        // 创建仓储和服务
        var productRepository = new MemoryRepository<Product>();
        var customerRepository = new MemoryRepository<Customer>();
        
        var productService = new ProductService(productRepository);
        var customerService = new CustomerService(customerRepository);
        
        // 添加产品
        Console.WriteLine("\n--- 添加产品 ---");
        productService.CreateEntity(new Product("笔记本电脑", 5999.99m, "电子产品", 50));
        productService.CreateEntity(new Product("无线鼠标", 199.99m, "电子产品", 100));
        productService.CreateEntity(new Product("机械键盘", 599.99m, "电子产品", 30));
        productService.CreateEntity(new Product("办公椅", 899.99m, "家具", 20));
        productService.CreateEntity(new Product("台灯", 299.99m, "家具", 5));
        
        // 添加客户
        Console.WriteLine("\n--- 添加客户 ---");
        customerService.CreateEntity(new Customer("张三", "zhangsan@email.com", "13800138000", "北京市朝阳区"));
        customerService.CreateEntity(new Customer("李四", "lisi@email.com", "13900139000", "上海市浦东新区"));
        customerService.CreateEntity(new Customer("王五", "wangwu@email.com", "13700137000", "广州市天河区"));
        
        // 查询产品
        Console.WriteLine("\n--- 产品查询 ---");
        var allProducts = productService.GetAllEntities();
        Console.WriteLine($"所有产品 ({allProducts.Count()}个):");
        foreach (var product in allProducts)
        {
            Console.WriteLine($"  {product}");
        }
        
        var electronicProducts = productService.GetProductsByCategory("电子产品");
        Console.WriteLine($"\n电子产品 ({electronicProducts.Count()}个):");
        foreach (var product in electronicProducts)
        {
            Console.WriteLine($"  {product}");
        }
        
        var affordableProducts = productService.GetProductsInPriceRange(100, 600);
        Console.WriteLine($"\n价格在100-600元的产品 ({affordableProducts.Count()}个):");
        foreach (var product in affordableProducts)
        {
            Console.WriteLine($"  {product}");
        }
        
        var lowStockProducts = productService.GetLowStockProducts(25);
        Console.WriteLine($"\n低库存产品 (≤25件) ({lowStockProducts.Count()}个):");
        foreach (var product in lowStockProducts)
        {
            Console.WriteLine($"  {product}");
        }
        
        // 查询客户
        Console.WriteLine("\n--- 客户查询 ---");
        var allCustomers = customerService.GetAllEntities();
        Console.WriteLine($"所有客户 ({allCustomers.Count()}个):");
        foreach (var customer in allCustomers)
        {
            Console.WriteLine($"  {customer}");
        }
        
        var customer = customerService.GetCustomerByEmail("lisi@email.com");
        Console.WriteLine($"\n邮箱为lisi@email.com的客户:{customer}");
        
        var customersWithWang = customerService.SearchCustomersByName("王");
        Console.WriteLine($"\n姓名包含'王'的客户 ({customersWithWang.Count()}个):");
        foreach (var c in customersWithWang)
        {
            Console.WriteLine($"  {c}");
        }
        
        // 更新和删除
        Console.WriteLine("\n--- 更新和删除操作 ---");
        var productToUpdate = productService.GetEntity(1);
        productToUpdate.Price = 5499.99m;
        productToUpdate.Stock = 45;
        productService.UpdateEntity(productToUpdate);
        Console.WriteLine($"更新后的产品:{productToUpdate}");
        
        productService.DeleteEntity(5);
        Console.WriteLine($"删除产品后,剩余产品数量:{productService.GetAllEntities().Count()}");
    }
}

2. 泛型方法和泛型委托

2.1 泛型方法

public static class GenericMethods
{
    // 基本泛型方法
    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;
    }
    
    public static T Max<T>(params T[] values) where T : IComparable<T>
    {
        if (values == null || values.Length == 0)
            throw new ArgumentException("至少需要一个值");
            
        T max = values[0];
        for (int i = 1; i < values.Length; i++)
        {
            if (values[i].CompareTo(max) > 0)
                max = values[i];
        }
        return max;
    }
    
    // 泛型搜索方法
    public static int BinarySearch<T>(T[] array, T target) where T : IComparable<T>
    {
        if (array == null)
            throw new ArgumentNullException(nameof(array));
            
        int left = 0;
        int right = array.Length - 1;
        
        while (left <= right)
        {
            int mid = left + (right - left) / 2;
            int comparison = array[mid].CompareTo(target);
            
            if (comparison == 0)
                return mid;
            else if (comparison < 0)
                left = mid + 1;
            else
                right = mid - 1;
        }
        
        return -1; // 未找到
    }
    
    // 泛型排序方法
    public static void QuickSort<T>(T[] array, int low = 0, int high = -1) where T : IComparable<T>
    {
        if (array == null)
            throw new ArgumentNullException(nameof(array));
            
        if (high == -1)
            high = array.Length - 1;
            
        if (low < high)
        {
            int pivotIndex = Partition(array, low, high);
            QuickSort(array, low, pivotIndex - 1);
            QuickSort(array, pivotIndex + 1, high);
        }
    }
    
    private static int Partition<T>(T[] array, int low, int high) where T : IComparable<T>
    {
        T pivot = array[high];
        int i = low - 1;
        
        for (int j = low; j < high; j++)
        {
            if (array[j].CompareTo(pivot) <= 0)
            {
                i++;
                Swap(ref array[i], ref array[j]);
            }
        }
        
        Swap(ref array[i + 1], ref array[high]);
        return i + 1;
    }
    
    // 泛型转换方法
    public static TOutput[] ConvertArray<TInput, TOutput>(TInput[] input, Func<TInput, TOutput> converter)
    {
        if (input == null)
            throw new ArgumentNullException(nameof(input));
        if (converter == null)
            throw new ArgumentNullException(nameof(converter));
            
        TOutput[] output = new TOutput[input.Length];
        for (int i = 0; i < input.Length; i++)
        {
            output[i] = converter(input[i]);
        }
        return output;
    }
    
    // 泛型过滤方法
    public static T[] Filter<T>(T[] array, Func<T, bool> predicate)
    {
        if (array == null)
            throw new ArgumentNullException(nameof(array));
        if (predicate == null)
            throw new ArgumentNullException(nameof(predicate));
            
        var result = new List<T>();
        foreach (T item in array)
        {
            if (predicate(item))
                result.Add(item);
        }
        return result.ToArray();
    }
    
    // 泛型聚合方法
    public static TResult Aggregate<T, TResult>(IEnumerable<T> source, TResult seed, Func<TResult, T, TResult> func)
    {
        if (source == null)
            throw new ArgumentNullException(nameof(source));
        if (func == null)
            throw new ArgumentNullException(nameof(func));
            
        TResult result = seed;
        foreach (T item in source)
        {
            result = func(result, item);
        }
        return result;
    }
    
    // 泛型缓存方法
    private static readonly Dictionary<string, object> cache = new Dictionary<string, object>();
    
    public static T GetOrCreate<T>(string key, Func<T> factory)
    {
        if (cache.TryGetValue(key, out object value))
        {
            return (T)value;
        }
        
        T newValue = factory();
        cache[key] = newValue;
        return newValue;
    }
    
    // 泛型单例方法
    public static T CreateSingleton<T>() where T : new()
    {
        return SingletonHelper<T>.Instance;
    }
    
    private static class SingletonHelper<T> where T : new()
    {
        public static readonly T Instance = new T();
    }
}

// 泛型方法使用示例
public class GenericMethodsDemo
{
    public static void DemonstrateGenericMethods()
    {
        Console.WriteLine("\n=== 泛型方法演示 ===");
        
        // 交换方法
        Console.WriteLine("\n--- 交换方法 ---");
        int a = 10, b = 20;
        Console.WriteLine($"交换前:a = {a}, b = {b}");
        GenericMethods.Swap(ref a, ref b);
        Console.WriteLine($"交换后:a = {a}, b = {b}");
        
        string str1 = "Hello", str2 = "World";
        Console.WriteLine($"交换前:str1 = {str1}, str2 = {str2}");
        GenericMethods.Swap(ref str1, ref str2);
        Console.WriteLine($"交换后:str1 = {str1}, str2 = {str2}");
        
        // 最大值方法
        Console.WriteLine("\n--- 最大值方法 ---");
        Console.WriteLine($"Max(10, 20) = {GenericMethods.Max(10, 20)}");
        Console.WriteLine($"Max(3.14, 2.71) = {GenericMethods.Max(3.14, 2.71)}");
        Console.WriteLine($"Max('A', 'Z') = {GenericMethods.Max('A', 'Z')}");
        Console.WriteLine($"Max(1, 5, 3, 9, 2) = {GenericMethods.Max(1, 5, 3, 9, 2)}");
        
        // 排序和搜索
        Console.WriteLine("\n--- 排序和搜索 ---");
        int[] numbers = { 64, 34, 25, 12, 22, 11, 90 };
        Console.WriteLine($"排序前:[{string.Join(", ", numbers)}]");
        
        GenericMethods.QuickSort(numbers);
        Console.WriteLine($"排序后:[{string.Join(", ", numbers)}]");
        
        int target = 25;
        int index = GenericMethods.BinarySearch(numbers, target);
        Console.WriteLine($"搜索 {target}:索引 = {index}");
        
        // 数组转换
        Console.WriteLine("\n--- 数组转换 ---");
        string[] stringNumbers = { "1", "2", "3", "4", "5" };
        int[] convertedNumbers = GenericMethods.ConvertArray(stringNumbers, int.Parse);
        Console.WriteLine($"字符串数组:[{string.Join(", ", stringNumbers)}]");
        Console.WriteLine($"转换为整数:[{string.Join(", ", convertedNumbers)}]");
        
        // 数组过滤
        Console.WriteLine("\n--- 数组过滤 ---");
        int[] allNumbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        int[] evenNumbers = GenericMethods.Filter(allNumbers, n => n % 2 == 0);
        Console.WriteLine($"所有数字:[{string.Join(", ", allNumbers)}]");
        Console.WriteLine($"偶数:[{string.Join(", ", evenNumbers)}]");
        
        // 聚合操作
        Console.WriteLine("\n--- 聚合操作 ---");
        int sum = GenericMethods.Aggregate(allNumbers, 0, (acc, n) => acc + n);
        string concatenated = GenericMethods.Aggregate(stringNumbers, "", (acc, s) => acc + s);
        Console.WriteLine($"数字求和:{sum}");
        Console.WriteLine($"字符串连接:{concatenated}");
        
        // 缓存和单例
        Console.WriteLine("\n--- 缓存和单例 ---");
        var list1 = GenericMethods.GetOrCreate("myList", () => new List<int> { 1, 2, 3 });
        var list2 = GenericMethods.GetOrCreate("myList", () => new List<int> { 4, 5, 6 });
        Console.WriteLine($"缓存测试 - 相同实例:{ReferenceEquals(list1, list2)}");
        
        var singleton1 = GenericMethods.CreateSingleton<StringBuilder>();
        var singleton2 = GenericMethods.CreateSingleton<StringBuilder>();
        Console.WriteLine($"单例测试 - 相同实例:{ReferenceEquals(singleton1, singleton2)}");
    }
}

2.2 泛型委托

// 自定义泛型委托
public delegate T GenericFunc<T>();
public delegate T GenericFunc<T, U>(U input);
public delegate void GenericAction<T>(T input);
public delegate bool GenericPredicate<T>(T input);
public delegate int GenericComparison<T>(T x, T y);

// 泛型事件处理
public class GenericEventArgs<T> : EventArgs
{
    public T Data { get; }
    public DateTime Timestamp { get; }
    
    public GenericEventArgs(T data)
    {
        Data = data;
        Timestamp = DateTime.Now;
    }
}

public delegate void GenericEventHandler<T>(object sender, GenericEventArgs<T> e);

// 泛型观察者模式
public class GenericObservable<T>
{
    private readonly List<Action<T>> observers = new List<Action<T>>();
    
    public event GenericEventHandler<T> DataChanged;
    
    public void Subscribe(Action<T> observer)
    {
        if (observer != null && !observers.Contains(observer))
        {
            observers.Add(observer);
        }
    }
    
    public void Unsubscribe(Action<T> observer)
    {
        observers.Remove(observer);
    }
    
    public void Notify(T data)
    {
        // 通知所有观察者
        foreach (var observer in observers.ToList())
        {
            try
            {
                observer(data);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"观察者通知失败:{ex.Message}");
            }
        }
        
        // 触发事件
        DataChanged?.Invoke(this, new GenericEventArgs<T>(data));
    }
    
    public int ObserverCount => observers.Count;
}

// 泛型命令模式
public interface IGenericCommand<T>
{
    void Execute(T parameter);
    bool CanExecute(T parameter);
}

public class GenericCommand<T> : IGenericCommand<T>
{
    private readonly Action<T> executeAction;
    private readonly Func<T, bool> canExecuteFunc;
    
    public GenericCommand(Action<T> executeAction, Func<T, bool> canExecuteFunc = null)
    {
        this.executeAction = executeAction ?? throw new ArgumentNullException(nameof(executeAction));
        this.canExecuteFunc = canExecuteFunc;
    }
    
    public void Execute(T parameter)
    {
        if (CanExecute(parameter))
        {
            executeAction(parameter);
        }
        else
        {
            throw new InvalidOperationException("命令无法执行");
        }
    }
    
    public bool CanExecute(T parameter)
    {
        return canExecuteFunc?.Invoke(parameter) ?? true;
    }
}

// 泛型工厂模式
public class GenericFactory<T>
{
    private readonly Dictionary<string, Func<T>> factories = new Dictionary<string, Func<T>>();
    
    public void Register(string key, Func<T> factory)
    {
        if (string.IsNullOrEmpty(key))
            throw new ArgumentException("键不能为空", nameof(key));
        if (factory == null)
            throw new ArgumentNullException(nameof(factory));
            
        factories[key] = factory;
    }
    
    public T Create(string key)
    {
        if (factories.TryGetValue(key, out Func<T> factory))
        {
            return factory();
        }
        throw new ArgumentException($"未找到工厂:{key}");
    }
    
    public bool IsRegistered(string key)
    {
        return factories.ContainsKey(key);
    }
    
    public IEnumerable<string> GetRegisteredKeys()
    {
        return factories.Keys;
    }
}

// 泛型委托使用示例
public class GenericDelegateDemo
{
    public static void DemonstrateGenericDelegates()
    {
        Console.WriteLine("\n=== 泛型委托演示 ===");
        
        // 基本泛型委托
        Console.WriteLine("\n--- 基本泛型委托 ---");
        GenericFunc<string> stringFactory = () => $"生成的字符串 {DateTime.Now:HH:mm:ss}";
        GenericFunc<int, string> intToString = x => $"数字:{x}";
        GenericAction<string> stringPrinter = s => Console.WriteLine($"打印:{s}");
        GenericPredicate<int> isEven = x => x % 2 == 0;
        
        string generatedString = stringFactory();
        stringPrinter(generatedString);
        stringPrinter(intToString(42));
        Console.WriteLine($"42是偶数:{isEven(42)}");
        Console.WriteLine($"43是偶数:{isEven(43)}");
        
        // 泛型观察者模式
        Console.WriteLine("\n--- 泛型观察者模式 ---");
        var observable = new GenericObservable<string>();
        
        // 订阅观察者
        observable.Subscribe(data => Console.WriteLine($"观察者1收到:{data}"));
        observable.Subscribe(data => Console.WriteLine($"观察者2收到:{data.ToUpper()}"));
        
        // 订阅事件
        observable.DataChanged += (sender, e) => 
            Console.WriteLine($"事件处理:{e.Data} (时间:{e.Timestamp:HH:mm:ss})");
        
        Console.WriteLine($"当前观察者数量:{observable.ObserverCount}");
        
        // 通知观察者
        observable.Notify("Hello World");
        observable.Notify("Generic Programming");
        
        // 泛型命令模式
        Console.WriteLine("\n--- 泛型命令模式 ---");
        var printCommand = new GenericCommand<string>(
            text => Console.WriteLine($"执行命令:{text}"),
            text => !string.IsNullOrEmpty(text)
        );
        
        var mathCommand = new GenericCommand<int>(
            number => Console.WriteLine($"计算结果:{number * number}"),
            number => number >= 0
        );
        
        try
        {
            printCommand.Execute("Hello Command");
            mathCommand.Execute(5);
            
            // 这会失败
            printCommand.Execute("");
        }
        catch (InvalidOperationException ex)
        {
            Console.WriteLine($"命令执行失败:{ex.Message}");
        }
        
        // 泛型工厂模式
        Console.WriteLine("\n--- 泛型工厂模式 ---");
        var stringFactory2 = new GenericFactory<string>();
        stringFactory2.Register("greeting", () => "Hello, World!");
        stringFactory2.Register("timestamp", () => DateTime.Now.ToString());
        stringFactory2.Register("guid", () => Guid.NewGuid().ToString());
        
        Console.WriteLine($"注册的工厂:[{string.Join(", ", stringFactory2.GetRegisteredKeys())}]");
        
        foreach (string key in stringFactory2.GetRegisteredKeys())
        {
            string value = stringFactory2.Create(key);
            Console.WriteLine($"{key}: {value}");
        }
        
        // 数字工厂
        var numberFactory = new GenericFactory<int>();
        numberFactory.Register("random", () => new Random().Next(1, 100));
        numberFactory.Register("timestamp", () => (int)DateTimeOffset.Now.ToUnixTimeSeconds());
        numberFactory.Register("constant", () => 42);
        
        Console.WriteLine("\n数字工厂:");
        foreach (string key in numberFactory.GetRegisteredKeys())
        {
            int value = numberFactory.Create(key);
            Console.WriteLine($"{key}: {value}");
        }
    }
}

3. 泛型约束

3.1 约束类型

// where T : class - 引用类型约束
public class ReferenceTypeContainer<T> where T : class
{
    private T item;
    
    public T Item
    {
        get => item;
        set => item = value; // 可以为null
    }
    
    public bool IsNull => item == null;
    
    public void SetToNull()
    {
        item = null; // 引用类型可以设置为null
    }
}

// where T : struct - 值类型约束
public class ValueTypeContainer<T> where T : struct
{
    private T item;
    private bool hasValue;
    
    public T Item
    {
        get => hasValue ? item : throw new InvalidOperationException("没有值");
        set
        {
            item = value;
            hasValue = true;
        }
    }
    
    public bool HasValue => hasValue;
    
    public T GetValueOrDefault(T defaultValue = default)
    {
        return hasValue ? item : defaultValue;
    }
    
    public void Clear()
    {
        item = default;
        hasValue = false;
    }
}

// where T : new() - 无参构造函数约束
public class Factory<T> where T : new()
{
    public T CreateInstance()
    {
        return new T();
    }
    
    public T[] CreateArray(int count)
    {
        T[] array = new T[count];
        for (int i = 0; i < count; i++)
        {
            array[i] = new T();
        }
        return array;
    }
    
    public List<T> CreateList(int count)
    {
        var list = new List<T>();
        for (int i = 0; i < count; i++)
        {
            list.Add(new T());
        }
        return list;
    }
}

// where T : BaseClass - 基类约束
public abstract class Shape
{
    public abstract double Area { get; }
    public abstract double Perimeter { get; }
    public abstract string Name { get; }
    
    public virtual void Draw()
    {
        Console.WriteLine($"绘制{Name}");
    }
}

public class Circle : Shape
{
    public double Radius { get; set; }
    
    public Circle() { }
    public Circle(double radius) => Radius = radius;
    
    public override double Area => Math.PI * Radius * Radius;
    public override double Perimeter => 2 * Math.PI * Radius;
    public override string Name => "圆形";
}

public class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }
    
    public Rectangle() { }
    public Rectangle(double width, double height)
    {
        Width = width;
        Height = height;
    }
    
    public override double Area => Width * Height;
    public override double Perimeter => 2 * (Width + Height);
    public override string Name => "矩形";
}

public class ShapeContainer<T> where T : Shape, new()
{
    private List<T> shapes = new List<T>();
    
    public void AddShape(T shape)
    {
        shapes.Add(shape);
    }
    
    public T CreateAndAddShape()
    {
        T shape = new T();
        shapes.Add(shape);
        return shape;
    }
    
    public double TotalArea => shapes.Sum(s => s.Area);
    public double TotalPerimeter => shapes.Sum(s => s.Perimeter);
    public int Count => shapes.Count;
    
    public void DrawAll()
    {
        foreach (T shape in shapes)
        {
            shape.Draw();
        }
    }
    
    public IEnumerable<T> GetShapes() => shapes.AsReadOnly();
}

// where T : IInterface - 接口约束
public interface IComparable<T>
{
    int CompareTo(T other);
}

public interface ICloneable<T>
{
    T Clone();
}

public class SortedContainer<T> where T : IComparable<T>
{
    private List<T> items = new List<T>();
    
    public void Add(T item)
    {
        int index = items.BinarySearch(item);
        if (index < 0)
            index = ~index;
        items.Insert(index, item);
    }
    
    public bool Remove(T item)
    {
        return items.Remove(item);
    }
    
    public T this[int index] => items[index];
    public int Count => items.Count;
    
    public bool Contains(T item)
    {
        return items.BinarySearch(item) >= 0;
    }
    
    public IEnumerable<T> GetItems() => items.AsReadOnly();
}

// 多重约束
public class CloneableRepository<T> where T : class, ICloneable<T>, new()
{
    private List<T> items = new List<T>();
    
    public void Add(T item)
    {
        items.Add(item);
    }
    
    public T GetCopy(int index)
    {
        if (index < 0 || index >= items.Count)
            throw new ArgumentOutOfRangeException(nameof(index));
        return items[index].Clone();
    }
    
    public List<T> GetAllCopies()
    {
        return items.Select(item => item.Clone()).ToList();
    }
    
    public T CreateNew()
    {
        return new T();
    }
    
    public int Count => items.Count;
}

// 示例可克隆类
public class Person : ICloneable<Person>, IComparable<Person>
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }
    
    public Person() { }
    
    public Person(string name, int age, string email)
    {
        Name = name;
        Age = age;
        Email = email;
    }
    
    public Person Clone()
    {
        return new Person(Name, Age, Email);
    }
    
    public int CompareTo(Person other)
    {
        if (other == null) return 1;
        
        int nameComparison = string.Compare(Name, other.Name, StringComparison.OrdinalIgnoreCase);
        if (nameComparison != 0) return nameComparison;
        
        return Age.CompareTo(other.Age);
    }
    
    public override string ToString()
    {
        return $"{Name}({Age}岁) - {Email}";
    }
    
    public override bool Equals(object obj)
    {
        return obj is Person person && Name == person.Name && Age == person.Age;
    }
    
    public override int GetHashCode()
    {
        return HashCode.Combine(Name, Age);
    }
}

3.2 泛型约束使用示例

public class GenericConstraintsDemo
{
    public static void DemonstrateGenericConstraints()
    {
        Console.WriteLine("\n=== 泛型约束演示 ===");
        
        // 引用类型约束
        Console.WriteLine("\n--- 引用类型约束 ---");
        var stringContainer = new ReferenceTypeContainer<string>();
        stringContainer.Item = "Hello World";
        Console.WriteLine($"字符串容器:{stringContainer.Item}");
        Console.WriteLine($"是否为null:{stringContainer.IsNull}");
        
        stringContainer.SetToNull();
        Console.WriteLine($"设置为null后:{stringContainer.IsNull}");
        
        var personContainer = new ReferenceTypeContainer<Person>();
        personContainer.Item = new Person("张三", 25, "zhangsan@email.com");
        Console.WriteLine($"人员容器:{personContainer.Item}");
        
        // 值类型约束
        Console.WriteLine("\n--- 值类型约束 ---");
        var intContainer = new ValueTypeContainer<int>();
        Console.WriteLine($"初始状态有值:{intContainer.HasValue}");
        Console.WriteLine($"默认值:{intContainer.GetValueOrDefault(999)}");
        
        intContainer.Item = 42;
        Console.WriteLine($"设置值后:{intContainer.Item}");
        Console.WriteLine($"现在有值:{intContainer.HasValue}");
        
        var dateTimeContainer = new ValueTypeContainer<DateTime>();
        dateTimeContainer.Item = DateTime.Now;
        Console.WriteLine($"日期时间容器:{dateTimeContainer.Item}");
        
        // 无参构造函数约束
        Console.WriteLine("\n--- 无参构造函数约束 ---");
        var personFactory = new Factory<Person>();
        Person newPerson = personFactory.CreateInstance();
        Console.WriteLine($"创建的新人员:{newPerson}");
        
        Person[] personArray = personFactory.CreateArray(3);
        Console.WriteLine($"创建的人员数组长度:{personArray.Length}");
        
        List<Person> personList = personFactory.CreateList(2);
        Console.WriteLine($"创建的人员列表数量:{personList.Count}");
        
        // 基类约束
        Console.WriteLine("\n--- 基类约束 ---");
        var circleContainer = new ShapeContainer<Circle>();
        circleContainer.CreateAndAddShape();
        
        var circle = new Circle(5.0);
        circleContainer.AddShape(circle);
        
        Console.WriteLine($"圆形容器中的形状数量:{circleContainer.Count}");
        Console.WriteLine($"总面积:{circleContainer.TotalArea:F2}");
        Console.WriteLine($"总周长:{circleContainer.TotalPerimeter:F2}");
        
        Console.WriteLine("绘制所有圆形:");
        circleContainer.DrawAll();
        
        // 接口约束
        Console.WriteLine("\n--- 接口约束 ---");
        var sortedPersons = new SortedContainer<Person>();
        sortedPersons.Add(new Person("张三", 25, "zhangsan@email.com"));
        sortedPersons.Add(new Person("李四", 30, "lisi@email.com"));
        sortedPersons.Add(new Person("王五", 20, "wangwu@email.com"));
        sortedPersons.Add(new Person("张三", 22, "zhangsan2@email.com")); // 同名但年龄不同
        
        Console.WriteLine($"排序后的人员 ({sortedPersons.Count}个):");
        foreach (Person person in sortedPersons.GetItems())
        {
            Console.WriteLine($"  {person}");
        }
        
        Console.WriteLine($"包含'李四(30岁)':{sortedPersons.Contains(new Person("李四", 30, "lisi@email.com"))}");
        
        // 多重约束
        Console.WriteLine("\n--- 多重约束 ---");
        var cloneableRepo = new CloneableRepository<Person>();
        cloneableRepo.Add(new Person("原始张三", 25, "original@email.com"));
        cloneableRepo.Add(new Person("原始李四", 30, "original2@email.com"));
        
        Console.WriteLine($"仓库中的人员数量:{cloneableRepo.Count}");
        
        Person copiedPerson = cloneableRepo.GetCopy(0);
        copiedPerson.Name = "复制的张三";
        copiedPerson.Email = "copied@email.com";
        
        Console.WriteLine($"原始人员:{cloneableRepo.GetAllCopies()[0]}");
        Console.WriteLine($"复制人员:{copiedPerson}");
        Console.WriteLine($"是同一个对象:{ReferenceEquals(cloneableRepo.GetCopy(0), copiedPerson)}");
        
        List<Person> allCopies = cloneableRepo.GetAllCopies();
        Console.WriteLine($"所有副本数量:{allCopies.Count}");
        
        Person newFromFactory = cloneableRepo.CreateNew();
        Console.WriteLine($"工厂创建的新人员:{newFromFactory}");
    }
}

4. 总结

本章深入介绍了C#泛型编程的核心概念:

  1. 泛型基础:泛型的概念、优势和基本使用
  2. 泛型类型:泛型类、泛型接口的定义和实现
  3. 泛型方法:泛型方法、泛型委托的使用
  4. 泛型约束:各种约束类型的使用和组合

关键要点: - 泛型提供类型安全和性能优势 - 避免装箱拆箱和类型转换 - 合理使用泛型约束限制类型参数 - 泛型方法可以独立于类进行类型推断 - 泛型委托支持函数式编程模式 - 多重约束可以组合使用

下一章预告: 下一章我们将学习委托和事件,包括委托的定义、多播委托、事件机制和观察者模式的实现。