1、C#泛型由CLR在运行时支持,编译为IL时使用占位符和特列的IL指令,JIT时再真正的泛型实例化,区别于C++的编译时模板机制和Java的搽试法。
a、可在各CLR语言之间无缝结合;
b、不会像C++产生代码膨胀问题;
c、也不会像Java的“假”泛型一样在性能上无所提升;
d、对于值类型,每种值类型实例化一份,对于引用类型,只实例化为同一份代码。
2、泛型类的要求
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
class A <T1,T2>
{
}//合法
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
class B:C <string,int>
{
} //合法
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
class D<U,V>:C<U,V>
{
} //合法
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
class E<U,V>:C<string,int>
{
} //合法
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
class G:C<U,V>
{
} //非法
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
/**//*
总之就是父类的类型参数要么从子类得到确定,如第三个,要么已经确定,如第四个,第五个的父类不能确定类型参数
*/
class A <T1,T2>
{
}//合法
class B:C <string,int>
{
} //合法
class D<U,V>:C<U,V>
{
} //合法
class E<U,V>:C<string,int>
{
} //合法
class G:C<U,V>
{
} //非法
/**//*
总之就是父类的类型参数要么从子类得到确定,如第三个,要么已经确定,如第四个,第五个的父类不能确定类型参数
*/
3、泛型类可以成为其它类的成员
class C<T>
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0be121fa5b8988fbabbbc526af3b0fc0.gif)
{
}
class D<T>
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0be121fa5b8988fbabbbc526af3b0fc0.gif)
{
public C<T> c;
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
public void DoThings()
![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
{
c.ToString();//没有用约束时,只能用object型的方法。
}
}
class C<T>
{
}
class D<T>
{
public C<T> c;
public void DoThings()
{
c.ToString();//没有用约束时,只能用object型的方法。
}
}
4、泛型接口的要求同2点
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
interface IList<T>
{T[] GetElements();}
interface IDictionary<T1,T2>
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0be121fa5b8988fbabbbc526af3b0fc0.gif)
{
void Add(T1 key, T2 value);
}
class List<T>:IList<T>,IDictionary<string,T>
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0be121fa5b8988fbabbbc526af3b0fc0.gif)
{
![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
public T[] GetElements()
{
}
![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
public void Add(string key, T value)
{
}
}
interface IList<T>
{T[] GetElements();}
interface IDictionary<T1,T2>
{
void Add(T1 key, T2 value);
}
class List<T>:IList<T>,IDictionary<string,T>
{
public T[] GetElements()
{
}
public void Add(string key, T value)
{
}
}
5、泛型委托
delegate bool Predicate<T>(T value);
class C
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0be121fa5b8988fbabbbc526af3b0fc0.gif)
{
![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
static bool F(int i )
{
}
![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
static bool G(string s)
{
}
static void Main()
![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
{
Predicate<string> p1 = G;//C#2.0新语法
Predicate<int> p2 = new Predicate<int>(F);//旧式语法写法
} d、泛型方法的重写
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
abstract class Base
{
public abstract T Function<T,T1>(T t, T1 t1)where T1:T;
public abstract T Function2<T> (T t) where T:IComparable;
}
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
class Derived:Base
{
![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
public override string Function<string,int>(string s, int i)
{}
![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
public override string Function2<string> (string s) where string:IComparable
{}//非法,重载无需声明约束
}
7、泛型约束--C#泛型的类型安全特点--要求显式的约束
a、基类约束
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
class Base
{public void F1()
{}}
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
class Derived<T> where T:Base
{
public void F2(T t)
![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
{
t.F1();//通过约束,能直接调用Base的方法
}
}
b、接口约束
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
interface I1
{void F1();}
class C<T> where T:I1
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0be121fa5b8988fbabbbc526af3b0fc0.gif)
{
//可以调用T继承的I1的F1方法
}
c、构造器约束
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
class A
{public A()
{}}
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
class B
{public B(int i)
{}}
class C<T> where T:new()
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0be121fa5b8988fbabbbc526af3b0fc0.gif)
{
//可以直接用T t = new T();实例化一个对象
}
C<A> c = new C<A>();//合法
C<B> c1 = new C<B>();//非法
d、值/引用类型约束
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
public struct A
{}
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
public class B
{}
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
public class C<T> where T:struct
{}
C<A> c = new C<A>();//合法
C<B> c1 = new C<B>(); //非法
delegate bool Predicate<T>(T value);
class C
{
static bool F(int i )
{
}
static bool G(string s)
{
}
static void Main()
{
Predicate<string> p1 = G;//C#2.0新语法
Predicate<int> p2 = new Predicate<int>(F);//旧式语法写法
} d、泛型方法的重写
abstract class Base
{
public abstract T Function<T,T1>(T t, T1 t1)where T1:T;
public abstract T Function2<T> (T t) where T:IComparable;
}
class Derived:Base
{
public override string Function<string,int>(string s, int i)
{}
public override string Function2<string> (string s) where string:IComparable
{}//非法,重载无需声明约束
}
7、泛型约束--C#泛型的类型安全特点--要求显式的约束
a、基类约束
class Base
{public void F1()
{}}
class Derived<T> where T:Base
{
public void F2(T t)
{
t.F1();//通过约束,能直接调用Base的方法
}
}
b、接口约束
interface I1
{void F1();}
class C<T> where T:I1
{
//可以调用T继承的I1的F1方法
}
c、构造器约束
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>();//合法
C<B> c1 = new C<B>();//非法
d、值/引用类型约束
public struct A
{}
public class B
{}
public class C<T> where T:struct
{}
C<A> c = new C<A>();//合法
C<B> c1 = new C<B>(); //非法
6、泛型方法--在方法声明上包含类型参数
a、C#不支持泛型索引、属性、事件、构造、析构,但这些成员可以使用类的泛型参数;
b、泛型方法可以用在泛和非泛类中
public class Finder
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0be121fa5b8988fbabbbc526af3b0fc0.gif)
{
public static Find<T>(T[] items, T item)
![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
{
for(int i = 0 ; i < items.length ; i++)
![](https://i-blog.csdnimg.cn/blog_migrate/3112b7b6526db5bc83e275260ae60525.gif)
{
if(items[i].Equal(item))return i;
}
return -1;
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
int i = Finder.Find<int>(new int[]
{1,2,3,4,5},2);
public class Finder
{
public static Find<T>(T[] items, T item)
{
for(int i = 0 ; i < items.length ; i++)
{
if(items[i].Equal(item))return i;
}
return -1;
}
}
int i = Finder.Find<int>(new int[]
{1,2,3,4,5},2);
c、泛型方法重载要求
void F1<T>(T[] a,int i);
void F1<U>(U[] a,int i); // Can't
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
void F2<T>(int i );
void F2(int i ); //yes
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
void F3 <T>(T t) where T:A
void F3 <T>(T t) where T:B //Can't
void F1<T>(T[] a,int i);
void F1<U>(U[] a,int i); // Can't
void F2<T>(int i );
void F2(int i ); //yes
void F3 <T>(T t) where T:A
void F3 <T>(T t) where T:B //Can't