完整教程:C#之开放泛型和闭合泛型

在 .NET 中,“开放泛型(Open Generic)” 和 “闭合泛型(Closed Generic)” 是对泛型类型状态的两种描述,尤其常见于反射、依赖注入、插件框架等场景中。


一句话理解

  • 开放泛型(Open Generic)定义了泛型参数,但还没有指定具体类型
  • 闭合泛型(Closed Generic):已经指定了所有泛型参数,成为一个完整的可用类型。

✅ 示例对比

类型表达式类型状态说明
List<>开放泛型定义了类型模板,还未指定元素类型
List<string>闭合泛型指定了元素类型 string
Dictionary<,>开放泛型有两个未指定的类型参数
Dictionary<int, string>闭合泛型所有参数都已指定

✅ 判断方式

Type t = typeof(List<
>);
Console.WriteLine(t.IsGenericType);
// true
Console.WriteLine(t.IsGenericTypeDefinition);
// true ← 开放泛型
Type t2 = typeof(List<
int>);
Console.WriteLine(t2.IsGenericType);
// true
Console.WriteLine(t2.IsGenericTypeDefinition);
// false ← 闭合泛型

✅ 在反射中的作用

✔ 判断类型是否实现某开放泛型接口:

Type type = typeof(MyRepository);
// 假设实现了 IRepository<string>
  Type openInterface = typeof(IRepository<
  >);
  bool implements = type.GetInterfaces()
  .Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == openInterface);

✔ 动态构造闭合泛型类型

Type openGeneric = typeof(List<
>);
Type closed = openGeneric.MakeGenericType(typeof(string));
// List<string>

✅ 应用场景

场景使用方式
依赖注入容器(如 Autofac)支持注册开放泛型,如 IRepo<>
插件系统加载时匹配泛型接口实现
构建表达式树 / 动态代理用开放泛型定义构建闭合类型
反射分析类型关系区分模板类型和已绑定类型

✅ 小结对比

特性开放泛型闭合泛型
是否具体可用❌ 不能直接 new 或调用✅ 可以直接使用
是否可构造实例
IsGenericType✅ 是✅ 是
IsGenericTypeDefinition✅ 是❌ 否
用途模板定义、泛型比较、动态构造实际使用

✅ 举个实战例子

假设你有一个服务接口 IHandler<T>,多个实现:

public interface IHandler<T> {
  void Handle(T item);
  }
  public class OrderHandler
  : IHandler<Order> {
    ...
    }
    public class UserHandler
    : IHandler<User> {
      ...
      }

你想通过反射找出实现了 IHandler<> 的所有类型

Type openGeneric = typeof(IHandler<
>);
var matches = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(t => t.GetInterfaces()
.Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == openGeneric));

posted @ 2025-09-18 13:38  yfceshi  阅读(9)  评论(0)    收藏  举报