 where泛型类型约束
where泛型类型约束
  在 C# 中,泛型类型约束(generic type constraint)是一种可以用来限制泛型类型参数的方式,它可以确保类型参数符合某些条件,以便在编写泛型代码时提供更多的类型安全性。其中的 where 关键字就是用来定义这些约束条件的。
本文将介绍 C#8.0 中的 where 关键字的使用方法及其各种约束条件,包括:
- 类型参数约束
- 基类约束
- 接口约束
- 新的通用约束
# 类型参数约束
类型参数约束是最基本的约束方式,它可以用来限制泛型类型参数必须是某个类型或其派生类。在 C#8.0 中,可以使用 where T : 类型名 的方式进行类型参数约束。
示例代码:
public class MyClass<T> where T : class
{
    // ...
}
在上面的示例中,T 必须是一个引用类型,因为 class 是一个引用类型的关键字。
另外,where T : struct 则表示 T 必须是一个值类型。
# 基类约束
基类约束可以用来确保泛型类型参数必须是某个指定类或其派生类。在 C#8.0 中,可以使用 where T : 基类名 的方式进行基类约束。
示例代码:
public class MyClass<T> where T : MyBaseClass
{
    // ...
}
在上面的示例中,T 必须是 MyBaseClass 类或其派生类。
# 接口约束
接口约束可以用来确保泛型类型参数必须实现某个指定接口。在 C#8.0 中,可以使用 where T : 接口名 的方式进行接口约束。
示例代码:
public class MyClass<T> where T : IMyInterface
{
    // ...
}
在上面的示例中,T 必须实现 IMyInterface 接口。
# 新的通用约束
C#8.0 中引入了一种新的通用约束方式,使用 where T : U 的方式表示泛型类型参数 T 必须可以转换为类型 U。
示例代码:
public class MyClass<T, U> where T : U
{
    // ...
}
在上面的示例中,T 必须是 U 类型或其派生类。
# 多个约束
可以在同一个泛型类型参数上同时应用多个约束条件。
示例代码:
public class MyClass<T> where T : MyBaseClass, IMyInterface, new()
{
    // ...
}
在上面的示例中,T 必须同时满足以下条件:
- 是 MyBaseClass
- 实现了 IMyInterface接口
- 具有无参数的公共构造函数
# where 子句的位置
where 子句可以出现在泛型类型定义的任何位置,例如在类定义中,也可以在方法定义中。
示例代码:
public class MyClass<T>
    where T : MyBaseClass
{
    // ...
 
    public void MyMethod<U>(U arg)
        where U : IMyInterface
    {
        // ...
    }
}
在上面的示例中,MyClass<T> 类定义中使用了基类约束,而 MyMethod<U> 方法定义中使用了接口约束。
# 总结
本文介绍了 C#8.0 中的 where 关键字,它可以用来限制泛型类型参数必须符合某些条件。包括类型参数约束、基类约束、接口约束和新的通用约束方式。此外,where 子句可以出现在泛型类型定义的任何位置,包括类定义和方法定义中。使用这些约束方式可以提供更多的类型安全性,减少程序错误的发生。
