▸ 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问答
学习建议
- 循序渐进:按照路径逐步深入,确保基础扎实
- 理论结合实践:每个知识点都要动手实现
- 阅读源码:研究.NET Core源码加深理解
- 性能意识:始终关注代码性能影响
- 持续更新:关注C#新版本特性