【整理】C#2.0泛型编程之泛型方法、泛型委托、泛型的属性与反射

泛型方法

    在C#2.0中,方法可以定义特定于其执行范围的泛型参数,如下所示:

    public class MyClass<T>
    {
        
//指定MyMethod方法用以执行类型为X的参数
        public void MyMethod<X>(X x) 
        {
            
//
        }

        
//此方法也可不指定方法参数
        public void MyMethod<X>() 
        {
            
//
        }
    }   

    即使包含类不适用泛型参数,你也可以定义方法特定的泛型参数,如下所示:

    public class MyClass
    {
        
//指定MyMethod方法用以执行类型为X的参数
        public void MyMethod<X>(X x) 
        {
            
//
        }

        
//此方法也可不指定方法参数
        public void MyMethod<X>() 
        {
            
//
        }
    }
    注意属性索引器不能指定自己的泛型参数,它们只能使用所属类中定义的泛型参数进行操作。
    在调用泛型方法的时候,你可以提供要在调用场所使用的类型,如下所示:
//调用泛型方法
MyClass myClass = new MyClass();
myClass.MyMethod
<int>(3);
    泛型推理:在调用泛型方法时,C#编译器足够聪明,基于传入的参数类型来推断出正确的类型,并且它允许完全省略类型规范,如下所示:
//泛型推理机制调用泛型方法
MyClass myClass = new MyClass();
myClass.MyMethod(
3);
    注意:泛型方法无法只根据返回值的类型推断出类型,代码如下:
     public GenericMethodDemo()
     {        
        MyClass myClass 
= new MyClass();
        
/****************************************************
        无法从用法中推理出方法“GenericMethodDemo.MyClass.MyMethod<T>()”的类型参数。
        请尝试显式指定类型参数。
        **************************************************
*/
        
int number = myClass.MyMethod();
     }

    
public class MyClass
    {
        
public T MyMethod<T>() 
        {
            
//
        }
    }
    泛型方法中泛型参数的约束,如下:
    public class MyClass
    {
        
        
public void MyMethod<X>(X x) where X:IComparable<X>
        {
            
//
        }
    }
    您无法为类级别的泛型参数提供方法级别的约束。类级别泛型参数的所有约束都必须在类作用范围中定义,代码如下所示
    public class MyClass<T>
    {
        
        
public void MyMethod<X>(X x,T t) where X:IComparable<X> where T:IComparer<T>
        {
            
//
        }
    }
而下面的代码是正确的
    public class MyClass<T> where T:IComparable<T>
    {
        
        
public void MyMethod<X>(X x,T t) where X:IComparable<X> 
        {
            
//
        }
    }
    泛型参数虚方法的重写:子类方法必须重新定义该方法特定的泛型参数,代码如下
    public class MyBaseClass
    {
        
public virtual void SomeMethod<T>(T t)
        {
            
//
        }
    }
    
public class MyClass :MyBaseClass
    {
        
public override void SomeMethod<X>(X x)
        {
            
        }
    }
同时子类中的泛型方法不能重复基类泛型方法的约束,这一点和泛型类中的虚方法重写是有区别的,代码如下
    public class MyBaseClass
    {
        
public virtual void SomeMethod<T>(T t) where T:new()
        {
            
//
        }
    }
    
public class MyClass :MyBaseClass
    {
        
//正确写法
        public override void SomeMethod<X>(X x)
        {
            
        }

        
////错误 重写和显式接口实现方法的约束是从基方法继承的,因此不能直接指定这些约束
        //public override void SomeMethod<X>(X x) where X:new()
        
//{

        
//}
    }
    子类方法调用虚拟方法的基类实现:它必须指定要代替泛型基础方法类型所使用的类型实参。你可以自己显式的指定它,也可以依靠类型推理(如果可能的话)代码如下:
    public class MyBaseClass
    {
        
public virtual void SomeMethod<T>(T t) where T:new()
        {
            
//
        }
    }
    
public class MyClass :MyBaseClass
    {
        
//正确写法
        public override void SomeMethod<X>(X x)
        {
            
base.SomeMethod<X>(x);
            
base.SomeMethod(x);
        }
    }
泛型委托
    在某个类中定义的委托可以使用该类的泛型参数,代码如下
    public class MyClass<T>
    {
        
public delegate void GenericDelegate(T t);
        
public void SomeMethod(T t)
        {
 
        }
    }
    
public GenericMethodDemo()
    {
        MyClass
<int> obj = new MyClass<int>();
        MyClass
<int>.GenericDelegate del;
        del 
= new MyClass<int>.GenericDelegate(obj.SomeMethod);
        del(
3);
    }
    委托推理:C#2.0使你可以将方法引用的直接分配转变为委托变量。将上面的代码改造如下
public class MyClass<T>
    {
        
public delegate void GenericDelegate(T t);
        
public void SomeMethod(T t)
        {
 
        }
    }
    
public GenericMethodDemo()
    {
        MyClass
<int> obj = new MyClass<int>();
        MyClass
<int>.GenericDelegate del;

        
//委托推理
      del = obj.SomeMethod;
        del(
3);
     }    
    泛型委托的约束:委托级别的约束只在声明委托变量和实例化委托时使用,类似于在类型和方法的作用范围中实施的其他任何约束。
泛型和反射
    在Net2.0当中,扩展了反射以支持泛型参数。类型Type现在可以表示带有特定类型的实参(或绑定类型)或未指定类型的泛型(或称未绑定类型)。像C#1.1中那样,您可以通过使用typeof运算符或通过调用每个类型支持的GetType()来获得任何类型的Type。代码如下:
 LinkedList<int> list = new LinkedList<int>();
 Type type1 
= typeof(LinkedList<int>);
 Type type2 
= list.GetType();
 Response.Write(type1 
== type2);
     typeof和GetType()也可以对泛型参数进行操作,如下
public class MyClass<T>
{
    
public void SomeMethod(T t)
    {
        Type type 
= typeof(T);
        HttpContext.Current.Response.Write(type
==t.GetType());
    }
}
    typeof还可以对未绑定的泛型进行操作,代码如下
    protected void Page_Load(object sender, EventArgs e)
    {
        
if (!IsPostBack)
        {
            Type unboundType 
= typeof(MyClass<>);
            Response.Write(unboundType.ToString());
        }
    }

    
public class MyClass<T>
    {
        
public void SomeMethod(T t)
        {
            Type type 
= typeof(T);
            HttpContext.Current.Response.Write(type
==t.GetType());
        }
    }
    请注意"<>"的用法。要对带有多个类型参数的未绑定泛型类进行操作,请在"<>"中使用","
    Type类中添加了新的方法和属性,用于提供有关该类型的泛型方面的反射信息,见MSDN。
posted @ 2009-06-13 10:19  网络渔夫  阅读(2121)  评论(0编辑  收藏  举报