泛型编程

class GenericStatc<T>   //T:类型参数,当然名字可以不必是T
    {
        T[] store;  //此处使用类型参数
        int index;

        public GenericStatc(int size)
        {
            this.store = new T[size];
            this.index = 0;
        }
        public void Push(T x)
        {
            store[index++] = x; //stre[index] = x;index++;

        }
        public T Pop()  //T用为返回类型
        {
            return store[--index]; 
        }
    }
C#泛型定义
1、通过参数化类型来达到类型的抽象化,从面得到更好的面向对象体验,C#泛型相对C++提供更强的类型安全。
2、实例化泛型类:
GenericStatc<string> strGStaic = new GenericStatc<string>(3);
C#泛型的底层机制
C#泛型代码在编译成IL代码和元数据时会是一个特殊的占位符,而只有在JIT运行时编译时才会实例化泛型类型,不象Java只是在编译时把代码编译为object
第一轮编译,编译器只为GenericStack<T>生成泛型板的IL代码和元数据,并不进行泛型类型的实例化,T在中间只是占位符
JIT编译时当JIT编译器第一次见到GenericStack<string>就会用string替换T---泛型的实例化
CLR为所有的引用类型产生同一份代码,而为值类型产生各自独立的代码,而java的假泛型会把值类型也转为object

C#泛型的特点
C#的泛型采用“基类,接口,构造器,值类型/引用类型”四种约束来对类型参数的“显示约束”。

C#泛型语法
C#可单独声明泛型类型或结构,也可以在基类中使用泛型类型的声明.
如果基类是泛型类型,它的类型参数要么已经实例化,要么由子类负责实例化
class C<A,B>{} //合法,单独声明泛型类型
class D:C<string,int>{} //合法,基类是泛型类型,它的类型参数已经实例化
class E<A,B>:C<A,B>{} //合法,基类是泛型类型,由子类负责实例化
class F<A,B>:C<string,int>{} //合法,基类是泛型类型,它的类型参数已经实例化
class G:C<A,B>{} //不合法,因为C<A,B>{}是一个引用类型,没有实例化,子类也没实例化基类的类型参数

泛型接口
泛型接口的类型参数要么已经实例化要么来源于实现接口的类
interface IList<T>
    {
        T[] GetElements();
    }
    interface IDictionary<A, B>
    {
        void Add(A key, B value);
    }
    class List<T> : IList<T>,IDictionary<int,T>
    {
        public T[] GetElements()
        {
            return null;
        }
        public void Add(int key, T value)
        {
           
        }
    }
泛型方法

1、可以在方法声明上包含类型参数
2、泛型不支持在方法外的其它成员(属性,事件,索引器,构造函数,析构函数)的声明上包含类型参数,但这些成员本身可以包含在泛型类型中,并使用泛型类型的类型参数
3、泛型方法可以包含在非泛型类型中
public class Finder
    {
        public static int Find<T>(T[] items, T item)
        {
            for (int i = 0; i < items.Length; i++)
            {
                if (item.Equals(items[i]))
                {
                    return i;
                }
            }
            return -1;
        }
    }
static void Main(string[] args)
        {
           
            int index = Finder.Find<string>(new string[] { "aa", "bb", "cc" }, "bb");
            Console.WriteLine(index);
        }
泛型方法的重载

class Traffic
    {
        //不能构成重载,因为两个类型不确定,有可能在传参时,类型一样,所有不能构成重载
        void F1<T>(T[] a, int i)
        { }
        void F1<U>(U[] a, int i)
        { }
        //可以构成重载
        void F2<T>(int x) { }
        void F2<T>(string x) { }
        //不能构成重载,自动报错了
        void F3<T>(T t) where T:A{}
        void F3<T>(T t) where T : B { }

    }
泛型方法的重写
abstract class Base
    {
        public abstract T F<A, B>(A a, B b) where B : A;
        public abstract T G<T>(A a) where T : IComparable;
    }
    public class Derive : Base
    {
        public override X F<A, B>(A a, B b) //合法,约束被默认继承
        {
            throw new NotImplementedException();
        }
    }
泛型约束
1、C#泛型要求对所有泛型类型或泛型方法的类型参数的任何假定,都要基于”显示的约束”,目的是维护.net所强调的的类型安全
2、约束由where子句表达,有基类,接口,构造器,值类型/引用类型四种约束
3、显示约束如果没有指定,泛型类型参数将只能访问Object类型中的公有方法

基类约束
class A { public void F1() { } }
    class B { public void F2() { } }
    class C<S, T>
        where S : A,new()
        where T : B
    {
        public void FF()
        {
            S s = new S();
            s.F1();
        }
       
    }
接口约束

 

posted @ 2009-10-27 21:10  flora_asp.net  阅读(291)  评论(2编辑  收藏  举报