C#的泛型支持包括类、结构、接口、委托共四种泛型类型,以及方法成员。
C#的泛型采用“基类,接口,构造器,值类型/引用类型”的结束方式来实现对类型参数的“显示约束”,它不支持C++模板那样的基于签名的隐式约束。
//
C#泛型演示
class Stack < T >
{
private T[] store;
private int size;
public Stack()
{
store = new T[ 10 ];
size = 0 ;
}
public void Push(T x)
{
store[size ++ ] = x;
}
public T Pop()
{
return store[ -- size];
}
}
所谓泛型,即通过参数化类型来实现在同一份代码上操作多种数据类型。泛型编程是一种编程范式,它利用“参数化类型”将类型抽象化,从而实现更为灵活的运用。
class Stack < T >
{
private T[] store;
private int size;
public Stack()
{
store = new T[ 10 ];
size = 0 ;
}
public void Push(T x)
{
store[size ++ ] = x;
}
public T Pop()
{
return store[ -- size];
}
}
所谓泛型,即通过参数化类型来实现在同一份代码上操作多种数据类型。泛型编程是一种编程范式,它利用“参数化类型”将类型抽象化,从而实现更为灵活的运用。
//
泛型类与结构
class C < U, V > { } // 合法
class D : C < string , int > { } // 合法
class E < U, V > : C < U, V > { } // 合法
class F < U, V > : C < string , int > { } // 合法
class G : C < U, V > { } // 非法
C#除可单独声明泛型类型(包括类与结构)外,也可在基类中包含泛型类型的声明。但基类如果是泛型类,它的类型参数要么实例化,要么来自于子类(同样是泛型类型)声明的类型参数。
class C < U, V > { } // 合法
class D : C < string , int > { } // 合法
class E < U, V > : C < U, V > { } // 合法
class F < U, V > : C < string , int > { } // 合法
class G : C < U, V > { } // 非法
C#除可单独声明泛型类型(包括类与结构)外,也可在基类中包含泛型类型的声明。但基类如果是泛型类,它的类型参数要么实例化,要么来自于子类(同样是泛型类型)声明的类型参数。
//
泛型类型的成员
class C < V >
{
public V f1; // 声明字段
public D < V > f2; // 作为其他泛型类型的参数
public C(V x)
{
this .f1 = x;
}
}
泛型类型的成员可以使用泛型类型声明中的类型参数。但类型参数如果没有任何约束,则只能在该类型上使用System.Object集成的公有成员。
class C < V >
{
public V f1; // 声明字段
public D < V > f2; // 作为其他泛型类型的参数
public C(V x)
{
this .f1 = x;
}
}
泛型类型的成员可以使用泛型类型声明中的类型参数。但类型参数如果没有任何约束,则只能在该类型上使用System.Object集成的公有成员。
//
泛型接口
interface IList < T >
{
T[] GetElements();
}
interface IDictionary < K, V >
{
void Add(K key, V value);
}
// 泛型接口的类型参数要么已经实例化,
// 要么来源于实现类声明的类型参数
class List < T > : IList < T > , IDictionary < int , T >
{
public T[] GetElements() { return null ; }
public void Add( int index, T value) { }
}
interface IList < T >
{
T[] GetElements();
}
interface IDictionary < K, V >
{
void Add(K key, V value);
}
// 泛型接口的类型参数要么已经实例化,
// 要么来源于实现类声明的类型参数
class List < T > : IList < T > , IDictionary < int , T >
{
public T[] GetElements() { return null ; }
public void Add( int index, T value) { }
}
//
泛型委托
delegate bool Predicate < T > (T value);
class X
{
static bool F( int i) {
}
static bool G( string s) {
}
static void Main( string [] args)
{
Predicate < string > p2 = G;
Predicate < int > p1 = new Predicate < int > (F);
}
}
泛型委托支持在委托返回值和参数上应用参数类型,这些参数类型同样支持可以附带合法的约束。
delegate bool Predicate < T > (T value);
class X
{
static bool F( int i) {
![](https://www.cnblogs.com/Images/dot.gif)
static bool G( string s) {
![](https://www.cnblogs.com/Images/dot.gif)
static void Main( string [] args)
{
Predicate < string > p2 = G;
Predicate < int > p1 = new Predicate < int > (F);
}
}
泛型委托支持在委托返回值和参数上应用参数类型,这些参数类型同样支持可以附带合法的约束。
//
泛型方法的声明和调用
public class Finder
{
// 泛型方法声明
public static int Find < T > (T[] items, T item)
{
for ( int i = 0 ; i < items.Length; i ++ )
{
if (items[i].Equals(item))
{
return i;
}
}
return - 1 ;
}
}
// 泛型方法调用
int i = Finder.Find < int > ( new int [] { 1 , 3 , 4 , 5 , 6 , 8 , 9 , }, 6 );
public class Finder
{
// 泛型方法声明
public static int Find < T > (T[] items, T item)
{
for ( int i = 0 ; i < items.Length; i ++ )
{
if (items[i].Equals(item))
{
return i;
}
}
return - 1 ;
}
}
// 泛型方法调用
int i = Finder.Find < int > ( new int [] { 1 , 3 , 4 , 5 , 6 , 8 , 9 , }, 6 );
//
泛型方法的重载
class MyClass
{
void F1 < T > (T[] a, int i);
void F1 < U > (U[] a, int i); // 不可以构成重载方法
void F2 < T > ( int x);
void F2( int x); // 可以构成重载
void F3 < T > (T t) where T : A;
void F3 < T > (T t) where T : B; // 不可以构成重载方法
}
class MyClass
{
void F1 < T > (T[] a, int i);
void F1 < U > (U[] a, int i); // 不可以构成重载方法
void F2 < T > ( int x);
void F2( int x); // 可以构成重载
void F3 < T > (T t) where T : A;
void F3 < T > (T t) where T : B; // 不可以构成重载方法
}
//
泛型方法的重写,泛型方法被覆盖时,约束被默认继承
abstract class Base
{
public abstract T F < T,U > (T t,U u) where U:T;
}
class Derived : Base
{
public override X F < X, Y > (X x, Y y)
{
}
}
泛型中的约束:基类约束
abstract class Base
{
public abstract T F < T,U > (T t,U u) where U:T;
}
class Derived : Base
{
public override X F < X, Y > (X x, Y y)
{
}
}
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
}
泛型中的约束:接口约束
class B { public void F2() { } }
class C < S, T >
where S : A // S继承自A
where T : B // T继承自B
{
// 可以在类型为S的变量上调用F1,
// 可以在类型为T的变量上调用F2
}
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
}
泛型中的约束:构造器约束
}
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
}
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没有无参构造器
泛型中的约束:值/引用类型约束
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没有无参构造器
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是一个引用类型
学习中,来源李建忠老师PPT
public class B { }
class C < T >
where T : struct
{
// T在这里面是一个值类型
}
C < A > c = new C < A > (); // 可以,A是一个值类型
C < B > c = new C < B > (); // 错误,B是一个引用类型