通过泛型方法定义具有特定类型意义的方法是常用的手段。但在某些特定情况下,例如在一些通用的框架中,直到运行时才能确定泛型类型参数,就必须通过非泛型方式来调用泛型方法。
假定有这样一个方法:
None.gif public   static   void  Add < T > (T obj, IList < T >  list)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif      list.Add(obj);
ExpandedBlockEnd.gif}

None.gif
如果想换成这样调用:
None.gif Add(Type type,  object  obj,  object  list);
通常的方法是这样的:
None.gif void  Add(Type type,  object  obj,  object  list)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    MethodInfo mi 
= typeof(MyType).GetMethod("Add");
InBlock.gif    MethodInfo gmi 
= mi.MakeGenericMethod(type);
ExpandedSubBlockStart.gifContractedSubBlock.gif    gmi.Invoke(
new object[] dot.gif{ obj, list });
ExpandedBlockEnd.gif}
当然,除了性能上的问题,这个方案是完全可行的。但是经过测试,通过这种包装后的耗时比直接的泛型调用相差将近1000倍。因此还需要一些折中一点的方案。为此,我请教了装配脑袋。他给出了一个非常好的方案:
先定义一个泛型包装委托:
None.gif public   delegate   void  GM < T > (T obj, IList < T >  list);
然后再定义一个非泛型包装的接口:
None.gif interface  ING
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
void NGM(object obj, object list);
ExpandedBlockEnd.gif}
然后再实现这个接口,在实现类中直接调用传入的泛型委托:
None.gif public   class  GClass < T >  : ING
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
private GM<T> m_gmd;
InBlock.gif
InBlock.gif    
public GClass(GM<T> gmd)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        m_gmd 
= gmd;
ExpandedSubBlockEnd.gif    }

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif    
INGClass 成员#region INGClass 成员
InBlock.gif
InBlock.gif    
public void NGM(object obj, object list)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        m_gmd((T)obj, (IList
<T>)list);
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockEnd.gif    
#endregion

ExpandedBlockEnd.gif}
然后就可以非常简单地使用已有的泛型方法来获得一个非泛型接口实现了:
None.gif static  ING GetNGC(Type genericType, Type methodType,  string  methodName)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    MethodInfo mi 
= methodType.GetMethod(methodName);
InBlock.gif    MethodInfo gmi 
= mi.MakeGenericMethod(genericType);
InBlock.gif    Delegate gmd 
= Delegate.CreateDelegate(typeof(GM<>).MakeGenericType(genericType), gmi);
InBlock.gif    
return Activator.CreateInstance(typeof(GClass<>).MakeGenericType(genericType), gmd) as ING;
ExpandedBlockEnd.gif}

None.gif
通过执行所返回接口的非泛型方法来达到调用泛型方法的目的:
None.gif ING ng  =  GetNGC( typeof ( int ),  typeof (MyType),  " Add " );
None.gifng.NGM(i, list);