(一)简化
Kanas.Net 对比的5种方案中,1、2、5 三种方案均需要在编译时指定所使用的类型,因此并未解决问题。方案3性能较低,方案4是有效方案:
·定义泛型委托;
·定义非泛型接口;
·实现这个接口;
·通过泛型委托获取非泛型接口的实现。
感觉方案4将问题复杂化了,这里采用委托用处不大,平添加许多复杂性。
我先前错误认为.net中的范型方法是在运行时才实例化的,装配脑袋 指出是在编译期实例化的,用reflector查看代码,正如装配脑袋所言,范型方法是在编译器实例化。因此,要解决以非范型方式调用范型方法的关键就在于在运行期产生指定类型范型方法。Kanas.Net 的方案4既是这个策略:
(1)申明一个非范型接口,用来持有运行期生成的方法,供后期调用;
(2)采用一个范型类,继承非范型接口
(3)一个方法,能够根据指定的类型名称,创建相应的范型类。
采用这种策略,更简洁的实现是引入helper:
1

public interface IServerClassHelper
2
{
3
void InvokeAdd(object obj, object list);
4
}
5

6

public class ServerClass
7
8
public void Add<T>(T obj, ICollection<T> c)
9
{
10
c.Add(obj);
11
}
12
13
public IServerClassHelper CreateHelper(Type T)
14
15
Type helperType = typeof(ServerClassHelper<>).MakeGenericType(T);
16
IServerClassHelper helper = Activator.CreateInstance(helperType, this) as IServerClassHelper;
17
return helper;
18
19
20
private sealed class ServerClassHelper<T> : IServerClassHelper
21
22
private ServerClass m_server;
23
24
public ServerClassHelper(ServerClass server)
25
{
26
m_server = server;
27
}
28
29
public void InvokeAdd(object obj, object list)
30
31
m_server.Add<T>((T)obj, (ICollection<T>)list);
32
33
34
使用:
1

ClientClassA a = new ClientClassA();
2

ICollection<ClientClassA> ca = new List<ClientClassA>();
3

String TypeString = "GenericMethodTest.ClientClassA";
4

IServerClassHelper helper = server.CreateHelper(Type.GetType(TypeString));
5

helper.InvokeAdd(a, ca);
性能测试:
1 : 2.09
(二)改进
上面方案使用起来还是比较复杂,首先需要获得一个helper,然后调用helper的相应方法。还是不够直接。继续改进吧,改进成<以非泛型方式调用泛型方法>一文开始所述接口:
Add(Type type, Object obj, Object c)。
以下是代码:

private static ICollection<IServerClassHelper> m_helpers = new List<IServerClassHelper>();
public void Add(Type type, Object obj, Object c)
GetHelper(type).InvokeAdd(obj, c);
private IServerClassHelper GetHelper(Type T)
foreach(IServerClassHelper h in m_helpers)
if (h.Equals(T)) return h;
IServerClassHelper helper = CreateHelper(T);
m_helpers.Add(helper);
private IServerClassHelper CreateHelper(Type T)
Type clientType = typeof(ServerClassHelper<>).MakeGenericType(T);
IServerClassHelper helper = Activator.CreateInstance(clientType, this, T) as IServerClassHelper;
private interface IServerClassHelper : IEquatable<Type>
本文转自xiaotie博客园博客,原文链接http://www.cnblogs.com/xiaotie/archive/2007/02/07/643947.html如需转载请自行联系原作者
xiaotie 集异璧实验室(GEBLAB)