C#2.0泛型学习

       C#的泛型能力有CLR在运行时支持,它既不同于C++在编译时所支持的静态模板,也不同于Java在编译器层面使用“搽拭法”支持的简单的泛型。
       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 C<U, V> { }  //合法

    
class D : C<stringint> { }  //合法

    
class E<U, V> : C<U, V> { }  //合法

    
class F<U, V> : C<stringint> { }  //合法

    
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集成的公有成员。

  //泛型接口
    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);
        }
    }
泛型委托支持在委托返回值和参数上应用参数类型,这些参数类型同样支持可以附带合法的约束。

    //泛型方法的声明和调用
    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[] { 1345689, }, 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;   //不可以构成重载方法

    }

    //泛型方法的重写,泛型方法被覆盖时,约束被默认继承
    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
    }
泛型中的约束:接口约束
 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 
    }
泛型中的约束:构造器约束
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没有无参构造器
泛型中的约束:值/引用类型约束
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
posted @ 2008-01-17 16:23  love .net FrameWork  阅读(735)  评论(2编辑  收藏  举报