C#泛型约束是指在定义泛型类型时,可以对泛型类型的参数进行限制,以保证使用该泛型类型的参数具有一定的特性。C#中支持两种泛型约束:一是where子句,二是typeof子句。
where子句用于限制泛型类型的参数必须具有某些特性,如必须实现某个接口、必须具有无参数的构造函数、必须是引用类型或者是一个特定的类。例如:
public class MyGenericClass<T> where T : IComparable, new() { public void DoSomething(T value) { // Do something with value } }
上述代码中,MyGenericClass<T> 的泛型参数 T 必须实现 IComparable 接口并且具有无参数的构造函数。
typeof子句用于限制泛型类型的参数必须是一个特定的引用或者是一个特定的类。例如:
public class MyGenericClass<T> where T : System.Type { public void DoSomething(T value) { // Do something with value } }
上述代码中,MyGenericClass<T> 的泛型参数 T 必须是 System.Type 类或者其子类。
C#中还有一些其他的泛型约束,如struct、class、enum、delegate、notnull 等。使用这些泛型约束能够帮助我们在使用泛型时提升代码质量并避免出错。
默认情况下,类型参数可以用任何类型替换。
约束可以应用于类型参数,以需要更具体的类型参数。
这些是可能的约束:
where T : base-class // Base-class constraint where T : interface // Interface constraint where T : class // Reference-type constraint where T : struct // Value-type constraint (excludes Nullable types) where T : new() // Parameterless constructor constraint where U : T // Naked type constraint
在下面的例子中,GenericClass <T,U>要求T从Main派生并实现Interface1,并且要求U提供一个无参数的构造函数:
class Main {} interface Interface1 {} class GenericClass<T,U> where T : Main, Interface1 where U : new() { ... }
约束可以应用于在方法和类型定义中定义类型参数的任何位置。
基类约束指定type参数必须对特定类进行子类化。
接口约束指定type参数必须实现该接口。
以下代码显示了如何编写一个通用Max方法,该方法最多返回两个值。
我们可以使用在框架中定义的通用接口IComparable <T>:
public interface IComparable<T> // Simplified version of interface { int CompareTo (T other); }
下面的代码使用IComparable接口作为约束,我们可以写一个Max方法如下:
static T Max <T> (T a, T b) where T : IComparable<T> { return a.CompareTo (b) > 0 ? a : b; }
Max方法可以接受任何类型的实现IComparable <T>的参数:
int z = Max (5, 10); // 10 string last = Max ("A", "B");
泛型类可以像非类类一样子类化。
子类可以保持基类的类型参数打开,如下例所示:
class Stack<T> {...} class SpecialStack<T> : Stack<T> {...}
或者子类可以使用具体类型关闭泛型类型参数:
class IntStack : Stack<int> {...}
一个子类型还可以引入新的类型参数:
class List<T> {...} class KeyedList<T,TKey> : List<T> {...}
C#对象初始化任何可访问的字段或对象的属性可以在构造之后通过对象初始化器直接设置。例如,考虑下面的类:public class Person ...
C#布尔类型/运算符C#的bool类型别名System.Boolean类型是一个逻辑值,可以分配文本true或false。我们使用bool类型来表示一个tu...