您可以在方法和属性的泛型类型中使用类型参数。例如,如果您有一个接受IList<T>
whereT
是您的类型参数的方法,您可以简单地执行以下操作:
public class GenericBuildService<T>
where T : INode
{
GenericBuildService(IList<T> dependencies, T rootNode);
}
然后T
,例如,如果是 ,MyNode
IntelliSense 将显示(并且编译器将验证)只有实现IList<MyNode>
的东西才会传递给您的构造函数(或使用的其他成员T
):
GenericBuildService(IList<MyNode> dependencies, MyNode rootNode);
要为不同类型参数指定多个where约束,可以重复where
关键字:
public class GenericBuildService<T, T2>
where T : INode
where TList : IList<T>
{
GenericBuildService(TList dependencies, T rootNode);
}
这意味着所有的使用TList
都被用户指定的任何类型所取代,但这种类型必须实现IList<T2>
。例如,如果TList
是,ReadOnlyCollection<MyNode>
那么 IntelliSense 将显示(并且编译器将验证)只有ReadOnlyCollection<MyNode>
对象被传递给您的构造函数:
GenericBuildService(ReadOnlyCollection<MyNode> dependencies, MyNode rootNode);
要在单个类型参数上指定多个约束,请用逗号分隔它们。首先指定特殊约束 ( struct
, class
),在接口之前指定类约束,new()
最后指定。
public class GenericBuildService<T, T2>
where T : class, IList<T2>, new()
{
}
您可以递归地在约束中使用类型参数。
约束指定类型必须是什么或实现什么。它们的含义:
class
: 只允许引用类型。引用类型可以是null
.
struct
: 只允许使用不可为空的值类型。这样的值类型不能是null
.
- 类约束:类型必须扩展指定的类型。
- 接口约束:该类型必须实现所有指定的接口。
new()
: 该类型必须有一个无参数的构造函数。所有值类型都有这样的构造函数,但引用类型可能有也可能没有。
您不能同时使用class
和 struct
。要指定您希望允许引用类型和所有值类型,请不要指定class
或根本不指定struct
。
如果您对泛型类型参数没有任何类型约束,则无需添加where
.
public class MyClass<T>
{
}