最近频繁的接触到泛型方面的问题,所以也不得不来学习一下了,开始主要是在MSDN的WebCast上去下载教学录象看的(李建忠老师的),本篇文章先介绍一下泛型入门方面的知识,希望能让刚开始学习泛型的朋友能够更快的入门,言归正传,首先我们来看一下泛型的基本概念:
      最显著的一点就是它参数化了类型,把类型作为参数抽象出来,从而使我们在实际的运用当中能够更好的实现代码的重复利用,同时它提供了更强的类型安全,更高 的效率,不过在约束方面,它只支持显示的约束,这样在灵活性方面就显得不是那么好了.我觉得它之所以能够提供更高的效率是因为泛型在实例化的时候采用了 "on-demand"的模式,即按需实例化,发生在JIT(Just In Time)编译时.
      下面来看如何定义一个泛型类,很简单,你只需要意识到一点,在这里,类型已经被参数化了:

C#2.0泛型学习--入门篇_分享using System;
C#2.0泛型学习--入门篇_分享using System.Collections.Generic;
C#2.0泛型学习--入门篇_分享using System.Text;
C#2.0泛型学习--入门篇_分享
C#2.0泛型学习--入门篇_分享namespace GenericTest
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07{
C#2.0泛型学习--入门篇_分享_08    class Program
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10    {
C#2.0泛型学习--入门篇_分享_08        static void Main(string[] args)
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10        {
C#2.0泛型学习--入门篇_分享_08            //使用string,int来实例化Test<T,S>类
C#2.0泛型学习--入门篇_分享_08            Test<string, int> t = new Test<string, int>("SHY520",22);
C#2.0泛型学习--入门篇_分享_08
C#2.0泛型学习--入门篇_分享_08            //调用泛型类中的方法
C#2.0泛型学习--入门篇_分享_08            t.SetValue();
C#2.0泛型学习--入门篇_分享_19        }
C#2.0泛型学习--入门篇_分享_19    }
C#2.0泛型学习--入门篇_分享_08
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10    /// <summary>
C#2.0泛型学习--入门篇_分享_08    /// 定义一个泛型类,该类有两个类型参数,分别是T,S
C#2.0泛型学习--入门篇_分享_08    /// </summary>
C#2.0泛型学习--入门篇_分享_08    /// <typeparam name="T">类型参数</typeparam>
C#2.0泛型学习--入门篇_分享_19    /// <typeparam name="S">类型参数</typeparam>
C#2.0泛型学习--入门篇_分享_08    public class Test<T,S>
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10    {
C#2.0泛型学习--入门篇_分享_08        //泛型类的类型参数可用于类成员
C#2.0泛型学习--入门篇_分享_08        private T name;
C#2.0泛型学习--入门篇_分享_08        private S age;
C#2.0泛型学习--入门篇_分享_08
C#2.0泛型学习--入门篇_分享_08        public Test(T Name,S Age)
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10        {
C#2.0泛型学习--入门篇_分享_08            this.name = Name;
C#2.0泛型学习--入门篇_分享_08            this.age = Age;
C#2.0泛型学习--入门篇_分享_19        }
C#2.0泛型学习--入门篇_分享_08
C#2.0泛型学习--入门篇_分享_08        public void SetValue()
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10        {
C#2.0泛型学习--入门篇_分享_08            Console.WriteLine(name.ToString());
C#2.0泛型学习--入门篇_分享_08            Console.WriteLine(age.ToString());
C#2.0泛型学习--入门篇_分享_19        }
C#2.0泛型学习--入门篇_分享_19    }
C#2.0泛型学习--入门篇_分享_49}


        上面的例子不是很恰当,目的是让初学泛型的你了解一下泛型的定义及实例化方法,如上,我们定义了一个泛型类,那么如何实现泛型类的继承呢?这里需要满足下面两点中的任何一点即可:
1、泛型类继承中,父类的类型参数已被实例化,这种情况下子类不一定必须是泛型类;
2、父类的类型参数没有被实例化,但来源于子类,也就是说父类和子类都是泛型类,并且二者有相同的类型参数;

C#2.0泛型学习--入门篇_分享    //如果这样写的话,显然会报找不到类型T,S的错误
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07    public class TestChild : Test<T, S> { }
C#2.0泛型学习--入门篇_分享
C#2.0泛型学习--入门篇_分享    //正确的写法应该是
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07    public class TestChild : Test<string, int>{ }
C#2.0泛型学习--入门篇_分享
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07    public class TestChild<T, S> : Test<T, S> { }
C#2.0泛型学习--入门篇_分享
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07    public class TestChild<T, S> : Test<String, int> { }


接着我们来看看泛型接口,其创建以及继承规则和上面说的泛型类是一样的,看下面的代码:

C#2.0泛型学习--入门篇_分享    public interface IList<T> 
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07    {
C#2.0泛型学习--入门篇_分享_08        T[] GetElements();
C#2.0泛型学习--入门篇_分享_49    } 
C#2.0泛型学习--入门篇_分享    public interface IDictionary<K,V>             
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07    {
C#2.0泛型学习--入门篇_分享_08        void Add(K key, V value); 
C#2.0泛型学习--入门篇_分享_49    } 
C#2.0泛型学习--入门篇_分享
C#2.0泛型学习--入门篇_分享    // 泛型接口的类型参数要么已实例化
C#2.0泛型学习--入门篇_分享    // 要么来源于实现类声明的类型参数
C#2.0泛型学习--入门篇_分享    class List<T> : IList<T>, IDictionary<int, T> 
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07    {
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10        public T[] GetElements() { return null; }
C#2.0泛型学习--入门篇_分享_08        public void Add(int index, T value) 
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10        { 
C#2.0泛型学习--入门篇_分享_19        }
C#2.0泛型学习--入门篇_分享_49    }
C#2.0泛型学习--入门篇_分享


在来看一下泛型委托,首先我们定义一个类型参数为T的委托,然后在类中利用委托调用方法:

C#2.0泛型学习--入门篇_分享using System;
C#2.0泛型学习--入门篇_分享using System.Collections.Generic;
C#2.0泛型学习--入门篇_分享using System.Text;
C#2.0泛型学习--入门篇_分享
C#2.0泛型学习--入门篇_分享namespace GenericTest
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07{
C#2.0泛型学习--入门篇_分享_08    //定义一个委托,类型参数为T,返回值类型T
C#2.0泛型学习--入门篇_分享_08    //泛型委托支持在返回值和参数上应用类型参数
C#2.0泛型学习--入门篇_分享_08    delegate string GenericDelete<T>(T value);
C#2.0泛型学习--入门篇_分享_08
C#2.0泛型学习--入门篇_分享_08    class test
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10    {
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10        static string F(int i) { return "SHY520"; }
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10        static string G(string s) { return "SHY520"; }
C#2.0泛型学习--入门篇_分享_08
C#2.0泛型学习--入门篇_分享_08        static void Main(string[] args)
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10        {
C#2.0泛型学习--入门篇_分享_08            GenericDelete<string> G1 = G;
C#2.0泛型学习--入门篇_分享_08            GenericDelete<int> G2 = new GenericDelete<int>(F);
C#2.0泛型学习--入门篇_分享_19        }
C#2.0泛型学习--入门篇_分享_19    } 
C#2.0泛型学习--入门篇_分享_49}


        我们再来看泛型方法,C#的泛型机制只支持在方法申明上包含类型参数,也即是泛型方法。特别注意的是,泛型不支持在除了方法以外的其他类/接口成员上使用 类型参数,但这些成员可以被包含在泛型类型中,并且可以使用泛型类型的类型参数。还有一点需要说的就是,泛型方法可以在泛型类型中,也可以存在于非泛型类 型中。下面我们分别看一下泛型类型的申明,调用,重载和覆盖。

C#2.0泛型学习--入门篇_分享using System;
C#2.0泛型学习--入门篇_分享using System.Collections.Generic;
C#2.0泛型学习--入门篇_分享using System.Text;
C#2.0泛型学习--入门篇_分享
C#2.0泛型学习--入门篇_分享namespace GenericTest
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07{
C#2.0泛型学习--入门篇_分享_08    class GenericClass
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10    {
C#2.0泛型学习--入门篇_分享_08        //申明一个泛型方法
C#2.0泛型学习--入门篇_分享_08        public T getvalue<T>(T t)
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10        {
C#2.0泛型学习--入门篇_分享_08            return t;
C#2.0泛型学习--入门篇_分享_19        }
C#2.0泛型学习--入门篇_分享_08
C#2.0泛型学习--入门篇_分享_08        //调用泛型方法
C#2.0泛型学习--入门篇_分享_08        //注意:在调用泛型方法时,对泛型方法的类型参数实例化
C#2.0泛型学习--入门篇_分享_08        public int useMethod()
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10        {
C#2.0泛型学习--入门篇_分享_08            return this.getvalue<int>(10);
C#2.0泛型学习--入门篇_分享_19        }
C#2.0泛型学习--入门篇_分享_08
C#2.0泛型学习--入门篇_分享_08        //重载getvalue方法
C#2.0泛型学习--入门篇_分享_08        public int getvalue(int i)
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10        {
C#2.0泛型学习--入门篇_分享_08            return i;
C#2.0泛型学习--入门篇_分享_19        }
C#2.0泛型学习--入门篇_分享_19    }
C#2.0泛型学习--入门篇_分享_08
C#2.0泛型学习--入门篇_分享_08    //下面演示覆盖
C#2.0泛型学习--入门篇_分享_08    //要注意的是,泛型方法被覆盖时,约束被默认继承,不需要重新指定约束关系
C#2.0泛型学习--入门篇_分享_08    abstract class Parent
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10    {
C#2.0泛型学习--入门篇_分享_08        public abstract K TEST<K, V>(K k, V v) where K : V;
C#2.0泛型学习--入门篇_分享_08
C#2.0泛型学习--入门篇_分享_19    }
C#2.0泛型学习--入门篇_分享_08
C#2.0泛型学习--入门篇_分享_08    class Child : Parent
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10    {
C#2.0泛型学习--入门篇_分享_08        public override T TEST<T, S>(T t, S s)
C#2.0泛型学习--入门篇_分享_09C#2.0泛型学习--入门篇_分享_10        {
C#2.0泛型学习--入门篇_分享_08            return t;
C#2.0泛型学习--入门篇_分享_19        }
C#2.0泛型学习--入门篇_分享_19    }
C#2.0泛型学习--入门篇_分享_49}
C#2.0泛型学习--入门篇_分享


        最后我们来看一下泛型中的约束:
        C#中的泛型只支持显示的约束,因为这样才能保证C#所要求的类型安全,但显示的约束并非时必须的,如果不加约束,泛型类型参数将只能访问 System.Object类型中的公有方法。“显式约束”由where子句表达,可以指定“基类约束”,“接口约束”,“构造器约束”,“值类型/引用 类型约束”共四种约束。下面的例子来源于李建忠老师的讲座PPT。
1、基类约束:

C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07    class A { public void F1() {} } 
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07    class B { public void F2() {} } 
C#2.0泛型学习--入门篇_分享    class C<S,T> 
C#2.0泛型学习--入门篇_分享    where S: A // S继承自A 
C#2.0泛型学习--入门篇_分享    where T: B // T继承自B 
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07    { 
C#2.0泛型学习--入门篇_分享_08    // 可以在类型为S的变量上调用F1,
C#2.0泛型学习--入门篇_分享_08    // 可以在类型为T的变量上调用F2 
C#2.0泛型学习--入门篇_分享_49    } 


2、接口约束

C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07    interface IPrintable { void Print(); 
C#2.0泛型学习--入门篇_分享_49    }
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07    interface IComparable<T> { int CompareTo(T v);}
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07    interface IKeyProvider<T> { T GetKey(); }
C#2.0泛型学习--入门篇_分享    class Dictionary<K,V> 
C#2.0泛型学习--入门篇_分享    where K: IComparable<K> 
C#2.0泛型学习--入门篇_分享    where V: IPrintable, IKeyProvider<K> 
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07    { 
C#2.0泛型学习--入门篇_分享_08    // 可以在类型为K的变量上调用CompareTo, 
C#2.0泛型学习--入门篇_分享_08    // 可以在类型为V的变量上调用Print和GetKey 
C#2.0泛型学习--入门篇_分享_49    }


3、构造器约束

C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07class A { public A() { } } 
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07class B { public B(int i) { } } 
C#2.0泛型学习--入门篇_分享class C<T> 
C#2.0泛型学习--入门篇_分享where T : new() 
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07
C#2.0泛型学习--入门篇_分享_08//可以在其中使用T t=new T();  
C#2.0泛型学习--入门篇_分享_49
C#2.0泛型学习--入门篇_分享C<A> c=new C<A>(); //可以,A有无参构造器
C#2.0泛型学习--入门篇_分享C<B> c=new C<B>(); //错误,B没有无参构造器


4、值/引用类型约束

C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07public struct A {  } 
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07public class B {  } 
C#2.0泛型学习--入门篇_分享class C<T> 
C#2.0泛型学习--入门篇_分享where T : struct 
C#2.0泛型学习--入门篇_分享_06C#2.0泛型学习--入门篇_分享_07
C#2.0泛型学习--入门篇_分享_08// T在这里面是一个值类型 
C#2.0泛型学习--入门篇_分享_49
C#2.0泛型学习--入门篇_分享C<A> c=new C<A>(); //可以,A是一个值类型
C#2.0泛型学习--入门篇_分享C<B> c=new C<B>(); //错误,B是一个引用类型


关于C#泛型入门的知识就这么多了,我也是对着李建忠老师的教学录像来学习的,初学的朋友也可以去下载录像来看: