上面的例子不是很恰当,目的是让初学泛型的你了解一下泛型的定义及实例化方法,如上,我们定义了一个泛型类,那么如何实现泛型类的继承呢?这里需要满足下面两点中的任何一点即可:1、泛型类继承中,父类的类型参数已被实例化,这种情况下子类不一定必须是泛型类;2、父类的类型参数没有被实例化,但来源于子类,也就是说父类和子类都是泛型类,并且二者有相同的类型参数;
// 如果这样写的话,显然会报找不到类型T,S的错误 public class TestChild : Test < T, S > { } // 正确的写法应该是 public class TestChild : Test < string , int > { } public class TestChild < T, S > : Test < T, S > { } public class TestChild < T, S > : Test < String, int > { } 接着我们来看看泛型接口,其创建以及继承规则和上面说的泛型类是一样的,看下面的代码: public interface IList < T > { T[] GetElements(); } public 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) { } } 在来看一下泛型委托,首先我们定义一个类型参数为T的委托,然后在类中利用委托调用方法: using System; using System.Collections.Generic; using System.Text; namespace GenericTest { //定义一个委托,类型参数为T,返回值类型T //泛型委托支持在返回值和参数上应用类型参数 delegate string GenericDelete<T>(T value); class test { static string F(int i) { return "SHY520"; } static string G(string s) { return "SHY520"; } static void Main(string[] args) { GenericDelete<string> G1 = G; GenericDelete<int> G2 = new GenericDelete<int>(F); } } }我们再来看泛型方法,C#的泛型机制只支持在方法申明上包含类型参数,也即是泛型方法。特别注意的是,泛型不支持在除了方法以外的其他类/接口成员上使用类型参数,但这些成员可以被包含在泛型类型中,并且可以使用泛型类型的类型参数。还有一点需要说的就是,泛型方法可以在泛型类型中,也可以存在于非泛型类型中。下面我们分别看一下泛型类型的申明,调用,重载和覆盖。
using System; using System.Collections.Generic; using System.Text; namespace GenericTest { class GenericClass { //申明一个泛型方法 public T getvalue<T>(T t) { return t; } //调用泛型方法 //注意:在调用泛型方法时,对泛型方法的类型参数实例化 public int useMethod() { return this.getvalue<int>(10); } //重载getvalue方法 public int getvalue(int i) { return i; } } //下面演示覆盖 //要注意的是,泛型方法被覆盖时,约束被默认继承,不需要重新指定约束关系 abstract class Parent { public abstract K TEST<K, V>(K k, V v) where K : V; } class Child : Parent { public override T TEST<T, S>(T t, S s) { return t; } }}最后我们来看一下泛型中的约束: 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是一个引用类型关于C#泛型入门的知识就这么多了,我也是对着李建忠老师的教学录像来学习的,初学的朋友也可以去下载录像来看:
http://www.microsoft.com/china/msdn/events/webcasts/shared/webcast/episode.aspx?newsID=1242246
学习泛型刚刚开始,希望能有高手指点,谢谢!