C#中的泛型只支持顯示的約束,因為這樣才能保證C#所要求的類型安全,但顯示的約束並非時必須的,如果不加約束,泛型類型參數將只能訪問System.Object類型中的公有方法。“顯式約束”由where子句表達,可以指定“基類約束”,“接口約束”,“構造器約束”,“值類型/引用類型約束”共四種約束。下面的例子來源於李建忠老師的講座PPT。
1、基類約束:
class A { public void F1() {} }
class B { public void F2() {} }
class C<S,T>
where S: A // S繼承自A
where T: B // T繼承自B
{
// 可以在類型為S的變量上調用F1,
// 可以在類型為T的變量上調用F2
}
2、接口約束
interface IPrintable { void Print(); }
interface IComparable<T> { int CompareTo(T v);}
interface IKeyProvider<T> { T GetKey(); }
class Dictionary<K,V>
where K: IComparable<K>
where V: IPrintable, IKeyProvider<K>
{
// 可以在類型為K的變量上調用CompareTo,
// 可以在類型為V的變量上調用Print和GetKey
}
3、構造器約束
class A { public A() { } }
class B { public B(int i) { } }
class C<T>
where T : new()
{
//可以在其中使用T t=new T();
}
C<A> c=new C<A>(); //可以,A有無參構造器
C<B> c=new C<B>(); //錯誤,B沒有無參構造器
4、值/引用類型約束
public struct A { }
public class B { }
class C<T>
where T : struct
{
// T在這裡面是一個值類型
}
C<A> c=new C<A>(); //可以,A是一個值類型
C<B> c=new C<B>(); //錯誤,B是一個引用類型