简而言之,您可以使用额外的标记来声明类型或方法来指示通用位:
class Foo<T> {
public Foo(T value) {
Value = value;
}
public T Value {get;private set;}
}
上面定义了一个泛型类型Foo
"of T
”,其中T
由调用者提供。按照惯例,泛型类型参数以 T 开头。如果只有一个,T
很好——否则可以用有用的方式命名它们:TSource
, TValue
, TListType
etc
与 C++ 模板不同,.NET 泛型由运行时提供(而不是编译器技巧)。例如:
Foo<int> foo = new Foo<int>(27);
All T
s 已替换为int
在上面。如有必要,您可以使用约束来限制泛型参数:
class Foo<T> where T : struct {}
Now Foo<string>
将拒绝编译 - 作为string
不是结构(值类型)。有效的约束是:
T : class // reference-type (class/interface/delegate)
T : struct // value-type except Nullable<T>
T : new() // has a public parameterless constructor
T : SomeClass // is SomeClass or inherited from SomeClass
T : ISomeInterface // implements ISomeInterface
约束还可以涉及其他泛型类型参数,例如:
T : IComparable<T> // or another type argument
您可以根据需要拥有任意数量的通用参数:
public struct KeyValuePair<TKey,TValue> {...}
其他注意事项:
- 定义静态成员等每个泛型类型组合- 所以有一个静态字段
Foo<int>
与上的那个是分开的Foo<float>
.
- 方法也可以是通用的 - 尽量避免使用与类使用相同的名称,因为您将无法消除歧义
- 嵌套类型从其父级继承泛型类型
例如:
class Foo<T> {
class Bar<TInner> {} // is effectively Bar<T,TInner>, for the outer T
}