▸ LOTO://SPACE
返回列表
▸ TECH

测试文章

#测试

C# 进阶知识

一、高级语言特性掌握

1. 1 深入理解泛型

1.1.1 泛型基础回顾与原理

1. 泛型的本质

泛型在编译时提供类型安全,在运行时由CLR支持。与C++模板不同,C#泛型是运行时特性。

// 编译时:List<T> 是开放类型
// 运行时:List<int> 是封闭类型
List<int> numbers = new List<int>();

// CLR会为每个值类型创建专门的类型
// 但引用类型共享同一份代码
List<string> strings = new List<string>();
List<object> objects = new List<object>(); // 这两个共享代码
2. 泛型的性能优势
// 非泛型版本 - 装箱/拆箱
ArrayList oldList = new ArrayList();
oldList.Add(42); // 装箱
int value = (int)oldList[0]; // 拆箱

// 泛型版本 - 无装箱
List<int> newList = new List<int>();
newList.Add(42); // 直接存储
int value2 = newList[0]; // 直接访问

1.1.2 泛型约束(Generic Constraints)

1. 基本约束类型
// where T : struct - 值类型约束
public class ValueContainer<T> where T : struct
{
    private T value;
    public T Value => value;
}

// where T : class - 引用类型约束
public class ReferenceContainer<T> where T : class
{
    private T reference;
    public bool IsNull => reference == null;
}

// where T : new() - 无参构造函数约束
public class Factory<T> where T : new()
{
    public T CreateInstance() => new T();
}
2. 接口和基类约束
// 接口约束,确保类型实现特定接口
public class Sorter<T> where T : IComparable<T>
{
    public void Sort(T[] array)
    {
        for (int i = 0; i < array.Length - 1; i++)
        {
            for (int j = i + 1; j < array.Length; j++)
            {
                if (array[i].CompareTo(array[j]) > 0)
                {
                    (array[i], array[j]) = (array[j], array[i]);
                }
            }
        }
    }
}

// 基类约束
public class AnimalHospital<T> where T : Animal
{
    public void Treat(T animal)
    {
        animal.Heal();
    }
}
3. 多重约束和组合约束
// 多重约束
public interface IRepository<T> 
    where T : class, IEntity, new()
{
    T Create();
    void Save(T entity);
}

// 泛型参数之间的约束
public class Converter<TInput, TOutput> 
    where TInput : class
    where TOutput : TInput, new()
{
    public TOutput Convert(TInput input)
    {
        // 转换逻辑
        return new TOutput();
    }
}
4. 高级约束技巧
// 使用 unmanaged 约束(C# 7.3+)
public unsafe struct UnmanagedArray<T> where T : unmanaged
{
    private T* data;
    private int length;
    
    public UnmanagedArray(int length)
    {
        this.length = length;
        data = (T*)Marshal.AllocHGlobal(sizeof(T) * length);
    }
}

// 使用 Enum 约束(C# 7.3+)
public static class EnumHelper<T> where T : Enum
{
    public static T[] GetValues() => Enum.GetValues<T>();
    
    public static bool TryParse(string value, out T result) =>
        Enum.TryParse(value, out result);
}

// 使用 Delegate 约束(C# 7.3+)
public class EventAggregator<T> where T : Delegate
{
    private T handlers;
    
    public void Subscribe(T handler)
    {
        handlers = (T)Delegate.Combine(handlers, handler);
    }
}

1.1.3 协变与逆变(Covariance & Contravariance)

设类型: C属于B,B属于A

要求:输出B类型,则输出B时,其输出类型要求比B类型更宽泛的也可,如A。(协变)

要求:输入B类型,则输入C时,其类型属于B类型,正确。(逆变)

1. 协变(out)
// 协变允许使用更派生的类型
public interface IProducer<out T>
{
    T Produce();// √ T在输出位置(返回值、只读属性)
    // void Consume(T item); × 编译错误!T不能在输入位置
}

public class AnimalProducer : IProducer<Animal>
{
    public Animal Produce() => new Dog();
}

// 使用协变
//允许使用比原始指定的派生类型更大的类型(子类型→父类型)
IProducer<Animal> animalProducer = new AnimalProducer();
IProducer<object> objectProducer = animalProducer; // 协变转换

// 内置协变接口,IEnumerable<out T> 是协变的
IEnumerable<string> strings = new List<string> { "a", "b" };
IEnumerable<object> objects = strings; // 可以,因为 IEnumerable<out T>

// IReadOnlyList<out T> 也是协变的
IReadOnlyList<Dog> dogs = new List<Dog>();
IReadOnlyList<Animal> animals = dogs;
2. 逆变(in)
// 逆变允许使用更基础的类型
public interface IConsumer<in T>
{
    void Consume(T item);// √ T在输入位置
    // T Produce(); × 编译错误!T不能在输出位置
}

public class ObjectConsumer : IConsumer<object>
{
    public void Consume(object item) 
    {
        Console.WriteLine(item?.ToString());
    }
}

// 使用逆变
IConsumer<object> objectConsumer = new ObjectConsumer();
IConsumer<string> stringConsumer = objectConsumer; // 逆变转换
stringConsumer.Consume(new string());//实际调用ObjectConsumer.Consume

// 内置逆变接口
Action<object> objectAction = obj => Console.WriteLine(obj);
Action<string> stringAction = objectAction; // 可以,因为 Action<in T>
3. 协变与逆变的限制
// 只能在接口和委托中使用
public interface ITransformer<in TInput, out TOutput>
{
    TOutput Transform(TInput input);
}

// 协变参数只能用作返回值
// 逆变参数只能用作输入参数
public interface IInvalidExample<out T>
{
    // void Process(T item); // 错误!out参数不能作为输入
    T GetItem(); // 正确
}

1.1.4 泛型方法与泛型委托

1. 泛型方法
public class Utilities
{
    // 泛型方法可以在非泛型类中
    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;
    }
    
    // 使用
    int x = 5, y = 10;
    Swap(ref x, ref y); // 类型推断,不需要 Swap<int>
}
2. 泛型委托
// 自定义泛型委托
public delegate TResult Transformer<in T, out TResult>(T input);

// 使用内置泛型委托
Func<int, string> intToString = i => i.ToString();
Predicate<string> isNullOrEmpty = string.IsNullOrEmpty;
Action<DateTime> printDate = date => Console.WriteLine(date);

// 委托的协变与逆变
Func<string, object> stringToObject = s => s;
Func<object, object> objectToObject = stringToObject; // 逆变
Func<string, string> stringToString = 
    (Func<string, string>)stringToObject; // 协变

1.1.5 自定义泛型集合

1. 实现一个简单的泛型栈
public class Stack<T> : IEnumerable<T>
{
    private T[] items;
    private int count;
    
    public Stack(int capacity = 16)
    {
        items = new T[capacity];
    }
    
    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("Stack is empty");
        
        T item = items[--count];
        items[count] = default(T); // 避免内存泄漏
        return item;
    }
    
    public IEnumerator<T> GetEnumerator()
    {
        for (int i = count - 1; i >= 0; i--)
            yield return items[i];
    }
    
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
2. 实现一个泛型缓存
public class Cache<TKey, TValue> 
    where TKey : notnull
    where TValue : class
{
    private readonly Dictionary<TKey, WeakReference> cache = new();
    private readonly Func<TKey, TValue> factory;
    
    public Cache(Func<TKey, TValue> factory)
    {
        this.factory = factory ?? throw new ArgumentNullException(nameof(factory));
    }
    
    public TValue GetOrCreate(TKey key)
    {
        if (cache.TryGetValue(key, out var weakRef) && 
            weakRef.Target is TValue value)
        {
            return value;
        }
        
        value = factory(key);
        cache[key] = new WeakReference(value);
        return value;
    }
}

1.1.6 泛型的高级应用

1. 泛型单例模式
public class Singleton<T> where T : class, new()
{
    private static readonly Lazy<T> instance = 
        new Lazy<T>(() => new T(), LazyThreadSafetyMode.ExecutionAndPublication);
    
    public static T Instance => instance.Value;
    
    protected Singleton() { }
}

// 使用
public class ConfigurationManager : Singleton<ConfigurationManager>
{
    public string GetSetting(string key) => "value";
}
2. 泛型工厂模式
public interface IFactory<out T>
{
    T Create();
}

public class Factory<T> : IFactory<T> where T : new()
{
    public virtual T Create() => new T();
}

public class SingletonFactory<T> : Factory<T> 
    where T : class, new()
{
    private readonly Lazy<T> instance = new(() => new T());
    
    public override T Create() => instance.Value;
}
3. 泛型仓储模式
public interface IRepository<T> where T : class, IEntity
{
    Task<T> GetByIdAsync(int id);
    Task<IEnumerable<T>> GetAllAsync();
    Task AddAsync(T entity);
    Task UpdateAsync(T entity);
    Task DeleteAsync(int id);
}

public abstract class RepositoryBase<T> : IRepository<T> 
    where T : class, IEntity
{
    protected readonly DbContext context;
    protected readonly DbSet<T> dbSet;
    
    protected RepositoryBase(DbContext context)
    {
        this.context = context;
        this.dbSet = context.Set<T>();
    }
    
    public virtual async Task<T> GetByIdAsync(int id)
    {
        return await dbSet.FindAsync(id);
    }
    
    // 其他方法实现...
}

1.1.7 性能考虑与最佳实践

1. 避免过度约束
// 不好的做法
public void Process<T>(T item) 
    where T : class, IComparable<T>, IEquatable<T>, new()
{
    // 过多约束限制了使用范围
}

// 好的做法
public void Process<T>(T item) where T : IComparable<T>
{
    // 只添加必要的约束
}
2. 合理使用泛型缓存
public static class TypeCache<T>
{
    public static readonly Type Type = typeof(T);
    public static readonly string TypeName = typeof(T).Name;
    public static readonly bool IsValueType = typeof(T).IsValueType;
    
    // 静态构造函数只执行一次
    static TypeCache()
    {
        Console.WriteLine($"TypeCache<{TypeName}> initialized");
    }
}
3. 注意装箱问题
public class Container<T>
{
    // 避免在泛型中使用会导致装箱的操作
    public bool IsDefault(T value)
    {
        // 不好:可能装箱
        // return value.Equals(default(T));
        
        // 好:使用 EqualityComparer
        return EqualityComparer<T>.Default.Equals(value, default(T));
    }
}

这些是C#泛型的核心高级概念。掌握这些知识将帮助您编写更加类型安全、高性能和可维护的代码。

  • 泛型约束(where子句)
  • 协变与逆变(out/in关键字)
  • 泛型方法与泛型委托
  • 自定义泛型集合

1.2 委托与事件进阶

  • 多播委托原理
  • 自定义事件访问器
  • 弱事件模式
  • 表达式树(Expression Trees)

1.3 LINQ深度探索

  • LINQ原理与延迟执行
  • 自定义LINQ扩展方法
  • 表达式树与动态查询
  • PLINQ并行查询

二、异步编程精通

1. Task并行库(TPL)

  • Task原理与调度器
  • TaskCompletionSource使用
  • 自定义异步模式
  • ConfigureAwait深入理解

2. 异步流(Async Streams)

  • IAsyncEnumerable接口
  • 异步迭代器
  • 取消令牌与超时处理

3. 并发集合与同步原语

  • ConcurrentCollections深入
  • 自定义同步原语
  • 无锁编程基础

三、内存管理与性能优化

1. 垃圾回收机制深入

  • GC算法与分代回收
  • 大对象堆(LOH)管理
  • 终结器与IDisposable模式
  • 弱引用与内存泄漏防范

2. 高性能编程

  • Span<T>与Memory<T>
  • ArrayPool与内存池
  • ref struct与栈分配
  • 性能计数器与BenchmarkDotNet

3. 不安全代码与互操作

  • unsafe上下文编程
  • 指针操作与固定内存
  • P/Invoke与COM互操作
  • 编组(Marshaling)技术

四、设计模式与架构

1. 高级设计模式实践

  • 依赖注入容器实现
  • AOP面向切面编程
  • 领域驱动设计(DDD)
  • CQRS与事件溯源

2. 反射与元编程

  • 反射性能优化
  • 动态代理实现
  • Roslyn编译器API
  • 源代码生成器

五、框架深入与扩展

1. ASP.NET Core内部机制

  • 中间件管道原理
  • 依赖注入容器源码
  • 自定义Host与Server
  • 性能优化技巧

2. Entity Framework Core进阶

  • 查询管道与表达式翻译
  • 变更跟踪机制
  • 性能调优与N+1问题
  • 自定义约定与拦截器

六、分布式与微服务

1. gRPC与远程调用

  • Protocol Buffers
  • 流式RPC实现
  • 拦截器与中间件

2. 消息队列与事件总线

  • RabbitMQ/Kafka集成
  • 分布式事务处理
  • Saga模式实现

七、实践项目建议

1. 实现一个迷你IoC容器

  • 理解依赖注入原理
  • 实现生命周期管理
  • 支持AOP扩展

2. 开发高性能缓存系统

  • 实现LRU/LFU算法
  • 支持分布式缓存
  • 内存优化与监控

3. 构建简易ORM框架

  • 表达式树解析
  • 对象映射与追踪
  • SQL生成与优化

学习资源推荐

书籍

  • 《CLR via C#》(深入理解CLR)
  • 《C# in Depth》(C#深度探索)
  • 《Pro .NET Memory Management》(.NET内存管理)

在线资源

  • Microsoft官方文档
  • .NET源码(GitHub)
  • Stephen Toub的博客(异步编程)
  • BenchmarkDotNet文档

实践平台

  • LeetCode(算法实践)
  • GitHub开源项目贡献
  • Stack Overflow问答

学习建议

  1. 循序渐进:按照路径逐步深入,确保基础扎实
  2. 理论结合实践:每个知识点都要动手实现
  3. 阅读源码:研究.NET Core源码加深理解
  4. 性能意识:始终关注代码性能影响
  5. 持续更新:关注C#新版本特性