比对一下,耗时大约是直接泛型调用耗时的三倍。显然这个方案是一个非常实用的方案。归纳一下,一共需要四步:
  • 定义泛型委托;
  • 定义非泛型接口;
  • 实现这个接口;
  • 通过泛型委托获取非泛型接口的实现。
其中前两步比较简单,后两部稍嫌麻烦。于是,我们再进一步实现一个通用的接口实现及其输出。
以非泛型方式调用泛型方法 (二)_职场using System;
以非泛型方式调用泛型方法 (二)_职场
using System.Collections.Generic;
以非泛型方式调用泛型方法 (二)_职场
using System.Reflection;
以非泛型方式调用泛型方法 (二)_职场
using System.Reflection.Emit;
以非泛型方式调用泛型方法 (二)_职场
using System.Text;
以非泛型方式调用泛型方法 (二)_职场
以非泛型方式调用泛型方法 (二)_职场
namespace GenericMethodTest
以非泛型方式调用泛型方法 (二)_职场_08
{
以非泛型方式调用泛型方法 (二)_休闲_11    
/// <summary>
以非泛型方式调用泛型方法 (二)_职场_13    
/// 接口生成器
以非泛型方式调用泛型方法 (二)_职场_14    
/// </summary>

以非泛型方式调用泛型方法 (二)_职场_13    internal static class InterfaceGenerator
以非泛型方式调用泛型方法 (二)_职场_16    
{
以非泛型方式调用泛型方法 (二)_职场_13        
private static Random _Random = new Random();
以非泛型方式调用泛型方法 (二)_职场_13
以非泛型方式调用泛型方法 (二)_职场_13        
private static char GetRandomLetter()
以非泛型方式调用泛型方法 (二)_职场_22        
{
以非泛型方式调用泛型方法 (二)_职场_13            
int i = (_Random.Next() % 26+ 97;
以非泛型方式调用泛型方法 (二)_职场_13            
byte[] b = BitConverter.GetBytes(i);
以非泛型方式调用泛型方法 (二)_职场_13            
return BitConverter.ToChar(b, 0);
以非泛型方式调用泛型方法 (二)_职场_14        }

以非泛型方式调用泛型方法 (二)_职场_13
以非泛型方式调用泛型方法 (二)_职场_13        
private static string GetRandomString(int n)
以非泛型方式调用泛型方法 (二)_休闲_31        
{
以非泛型方式调用泛型方法 (二)_职场_13            
char[] chars = new char[n];
以非泛型方式调用泛型方法 (二)_职场_13            
for (int i = 0; i < n; i++)
以非泛型方式调用泛型方法 (二)_泛型_36            
{
以非泛型方式调用泛型方法 (二)_职场_13                chars[i] 
= GetRandomLetter();
以非泛型方式调用泛型方法 (二)_职场_14            }

以非泛型方式调用泛型方法 (二)_职场_13            
return new string(chars);
以非泛型方式调用泛型方法 (二)_职场_14        }

以非泛型方式调用泛型方法 (二)_职场_13
以非泛型方式调用泛型方法 (二)_职场_13        
private static void LoadArg(ILGenerator gen, int index)
以非泛型方式调用泛型方法 (二)_职场_45        
{
以非泛型方式调用泛型方法 (二)_职场_13            
switch (index)
以非泛型方式调用泛型方法 (二)_泛型_49            
{
以非泛型方式调用泛型方法 (二)_职场_13                
case 0:
以非泛型方式调用泛型方法 (二)_职场_13                    gen.Emit(OpCodes.Ldarg_0);
以非泛型方式调用泛型方法 (二)_职场_13                    
break;
以非泛型方式调用泛型方法 (二)_职场_13                
case 1:
以非泛型方式调用泛型方法 (二)_职场_13                    gen.Emit(OpCodes.Ldarg_1);
以非泛型方式调用泛型方法 (二)_职场_13                    
break;
以非泛型方式调用泛型方法 (二)_职场_13                
case 2:
以非泛型方式调用泛型方法 (二)_职场_13                    gen.Emit(OpCodes.Ldarg_2);
以非泛型方式调用泛型方法 (二)_职场_13                    
break;
以非泛型方式调用泛型方法 (二)_职场_13                
case 3:
以非泛型方式调用泛型方法 (二)_职场_13                    gen.Emit(OpCodes.Ldarg_3);
以非泛型方式调用泛型方法 (二)_职场_13                    
break;
以非泛型方式调用泛型方法 (二)_职场_13                
default:
以非泛型方式调用泛型方法 (二)_职场_13                    
if (index < 128)
以非泛型方式调用泛型方法 (二)_泛型_66                    
{
以非泛型方式调用泛型方法 (二)_职场_13                        gen.Emit(OpCodes.Ldarg_S, index);
以非泛型方式调用泛型方法 (二)_职场_14                    }

以非泛型方式调用泛型方法 (二)_职场_13                    
else
以非泛型方式调用泛型方法 (二)_泛型_72                    
{
以非泛型方式调用泛型方法 (二)_职场_13                        gen.Emit(OpCodes.Ldarg, index);
以非泛型方式调用泛型方法 (二)_职场_14                    }

以非泛型方式调用泛型方法 (二)_职场_13                    
break;
以非泛型方式调用泛型方法 (二)_职场_14            }

以非泛型方式调用泛型方法 (二)_职场_14        }

以非泛型方式调用泛型方法 (二)_职场_13
以非泛型方式调用泛型方法 (二)_职场_13        
public static T GetInterface<T>(Delegate GM)
以非泛型方式调用泛型方法 (二)_泛型_82        
{
以非泛型方式调用泛型方法 (二)_职场_13            
if (typeof(T).IsInterface)
以非泛型方式调用泛型方法 (二)_职场_86            
{
以非泛型方式调用泛型方法 (二)_职场_13                Type delegateType 
= GM.GetType();
以非泛型方式调用泛型方法 (二)_职场_13                
if (delegateType.IsGenericType)
以非泛型方式调用泛型方法 (二)_休闲_91                
{
以非泛型方式调用泛型方法 (二)_职场_13                    
if (typeof(MulticastDelegate).IsAssignableFrom(delegateType.GetGenericTypeDefinition()))
以非泛型方式调用泛型方法 (二)_泛型_95                    
{
以非泛型方式调用泛型方法 (二)_职场_13                        Type[] genericTypes 
= delegateType.GetGenericArguments();
以非泛型方式调用泛型方法 (二)_职场_13                        
if (genericTypes.Length == 1)
以非泛型方式调用泛型方法 (二)_职场_100                        
{
以非泛型方式调用泛型方法 (二)_职场_13                            Type genericType 
= genericTypes[0];
以非泛型方式调用泛型方法 (二)_职场_13
以非泛型方式调用泛型方法 (二)_职场_13
#if SAVE
以非泛型方式调用泛型方法 (二)_职场_13                            
string theFilename = "InterfaceGenerator.Attachments.dll";
以非泛型方式调用泛型方法 (二)_职场_13
#endif
以非泛型方式调用泛型方法 (二)_职场_13                            AssemblyName aname 
= new AssemblyName();
以非泛型方式调用泛型方法 (二)_职场_13                            aname.Name 
= string.Format("InterfaceGenerator.Attachments.{0}", GetRandomString(16));
以非泛型方式调用泛型方法 (二)_职场_13                            aname.Version 
= new Version("2.0.0.0");
以非泛型方式调用泛型方法 (二)_职场_13                            AssemblyBuilder assembly 
= AppDomain.CurrentDomain.DefineDynamicAssembly(aname,
以非泛型方式调用泛型方法 (二)_职场_13
#if SAVE
以非泛型方式调用泛型方法 (二)_职场_13 AssemblyBuilderAccess.RunAndSave
以非泛型方式调用泛型方法 (二)_职场_13
#else
以非泛型方式调用泛型方法 (二)_职场_13 AssemblyBuilderAccess.Run
以非泛型方式调用泛型方法 (二)_职场_13
#endif
以非泛型方式调用泛型方法 (二)_职场_13);
以非泛型方式调用泛型方法 (二)_职场_13                            ModuleBuilder module 
= assembly.DefineDynamicModule(GetRandomString(8)
以非泛型方式调用泛型方法 (二)_职场_13
#if SAVE
以非泛型方式调用泛型方法 (二)_职场_13, theFilename
以非泛型方式调用泛型方法 (二)_职场_13
#endif
以非泛型方式调用泛型方法 (二)_职场_13);
以非泛型方式调用泛型方法 (二)_职场_13                            TypeBuilder builder 
= module.DefineType(GetRandomString(16), TypeAttributes.Sealed | TypeAttributes.Class | TypeAttributes.Public);
以非泛型方式调用泛型方法 (二)_职场_13                            builder.AddInterfaceImplementation(
typeof(T));
以非泛型方式调用泛型方法 (二)_职场_13
以非泛型方式调用泛型方法 (二)_职场_13                            
// 先定义成员域,用于保存传入的委托。
以非泛型方式调用泛型方法 (二)_职场_13
                            FieldBuilder field = builder.DefineField(GetRandomString(8), delegateType, FieldAttributes.Private);
以非泛型方式调用泛型方法 (二)_职场_13
以非泛型方式调用泛型方法 (二)_职场_13                            
// 定义构造器。
以非泛型方式调用泛型方法 (二)_泛型_130
                            ConstructorBuilder ctor = builder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { delegateType });
以非泛型方式调用泛型方法 (二)_职场_13                            ILGenerator ctorGen 
= ctor.GetILGenerator();
以非泛型方式调用泛型方法 (二)_职场_13                            ctorGen.Emit(OpCodes.Ldarg_0);
以非泛型方式调用泛型方法 (二)_泛型_135                            ctorGen.Emit(OpCodes.Call, 
typeof(object).GetConstructor(new Type[] { }));
以非泛型方式调用泛型方法 (二)_职场_13                            ctorGen.Emit(OpCodes.Ldarg_0);
以非泛型方式调用泛型方法 (二)_职场_13                            ctorGen.Emit(OpCodes.Ldarg_1);
以非泛型方式调用泛型方法 (二)_职场_13                            ctorGen.Emit(OpCodes.Stfld, field);
以非泛型方式调用泛型方法 (二)_职场_13                            ctorGen.Emit(OpCodes.Ret);
以非泛型方式调用泛型方法 (二)_职场_13
以非泛型方式调用泛型方法 (二)_职场_13                            
// 虽然这么写,但事实上接口只有一个方法。
以非泛型方式调用泛型方法 (二)_职场_13
                            foreach (MethodInfo bmi in typeof(T).GetMethods())
以非泛型方式调用泛型方法 (二)_职场_145                            
{
以非泛型方式调用泛型方法 (二)_职场_13                                ParameterInfo[] paramInfos 
= bmi.GetParameters();
以非泛型方式调用泛型方法 (二)_职场_13                                Type[] argTypes 
= new Type[paramInfos.Length];
以非泛型方式调用泛型方法 (二)_职场_13                                
int i = 0;
以非泛型方式调用泛型方法 (二)_职场_13                                
foreach (ParameterInfo pi in paramInfos)
以非泛型方式调用泛型方法 (二)_职场_152                                
{
以非泛型方式调用泛型方法 (二)_职场_13                                    argTypes[i
++= pi.ParameterType;
以非泛型方式调用泛型方法 (二)_职场_14                                }

以非泛型方式调用泛型方法 (二)_职场_13                                MethodAttributes attributes 
= MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.ReuseSlot | MethodAttributes.Public;
以非泛型方式调用泛型方法 (二)_职场_13                                MethodBuilder method 
= builder.DefineMethod(bmi.Name, attributes, bmi.ReturnType, argTypes);
以非泛型方式调用泛型方法 (二)_职场_13                                builder.DefineMethodOverride(method, bmi);
以非泛型方式调用泛型方法 (二)_职场_13                                MethodInfo dmi 
= delegateType.GetMethod("Invoke");
以非泛型方式调用泛型方法 (二)_职场_13                                ILGenerator methodGen 
= method.GetILGenerator();
以非泛型方式调用泛型方法 (二)_职场_13                                
bool hasReturn = false;
以非泛型方式调用泛型方法 (二)_职场_13                                
if (dmi.ReturnType != typeof(void))
以非泛型方式调用泛型方法 (二)_休闲_164                                
{
以非泛型方式调用泛型方法 (二)_职场_13                                    methodGen.DeclareLocal(dmi.ReturnType);
以非泛型方式调用泛型方法 (二)_职场_13                                    hasReturn 
= true;
以非泛型方式调用泛型方法 (二)_职场_14                                }

以非泛型方式调用泛型方法 (二)_职场_13                                methodGen.Emit(OpCodes.Ldarg_0);
以非泛型方式调用泛型方法 (二)_职场_13                                methodGen.Emit(OpCodes.Ldfld, field);
以非泛型方式调用泛型方法 (二)_职场_13
以非泛型方式调用泛型方法 (二)_职场_13                                i 
= 0;
以非泛型方式调用泛型方法 (二)_职场_13                                
foreach (ParameterInfo pi in dmi.GetParameters())
以非泛型方式调用泛型方法 (二)_休闲_175                                
{
以非泛型方式调用泛型方法 (二)_职场_13                                    LoadArg(methodGen, i 
+ 1);
以非泛型方式调用泛型方法 (二)_职场_13                                    
if (!pi.ParameterType.IsAssignableFrom(argTypes[i]))
以非泛型方式调用泛型方法 (二)_休闲_180                                    
{
以非泛型方式调用泛型方法 (二)_职场_13                                        
if (argTypes[i].IsClass)
以非泛型方式调用泛型方法 (二)_泛型_184                                        
{
以非泛型方式调用泛型方法 (二)_职场_13                                            methodGen.Emit(OpCodes.Castclass, pi.ParameterType);
以非泛型方式调用泛型方法 (二)_职场_14                                        }

以非泛型方式调用泛型方法 (二)_职场_13                                        
else
以非泛型方式调用泛型方法 (二)_职场_190                                        
{
以非泛型方式调用泛型方法 (二)_职场_13                                            methodGen.Emit(OpCodes.Unbox, pi.ParameterType);
以非泛型方式调用泛型方法 (二)_职场_14                                        }

以非泛型方式调用泛型方法 (二)_职场_14                                    }

以非泛型方式调用泛型方法 (二)_职场_13                                    i
++;
以非泛型方式调用泛型方法 (二)_职场_14                                }

以非泛型方式调用泛型方法 (二)_职场_13                                methodGen.Emit(OpCodes.Callvirt, dmi);
以非泛型方式调用泛型方法 (二)_职场_13                                
if (hasReturn)
以非泛型方式调用泛型方法 (二)_职场_200                                
{
以非泛型方式调用泛型方法 (二)_职场_13                                    methodGen.Emit(OpCodes.Stloc_0);
以非泛型方式调用泛型方法 (二)_职场_13                                    methodGen.Emit(OpCodes.Ldloc_0);
以非泛型方式调用泛型方法 (二)_职场_14                                }

以非泛型方式调用泛型方法 (二)_职场_13                                methodGen.Emit(OpCodes.Ret);
以非泛型方式调用泛型方法 (二)_职场_14                            }

以非泛型方式调用泛型方法 (二)_职场_13                            Type target 
= builder.CreateType();
以非泛型方式调用泛型方法 (二)_职场_13
#if SAVE
以非泛型方式调用泛型方法 (二)_职场_13                            assembly.Save(theFilename);
以非泛型方式调用泛型方法 (二)_职场_13
#endif
以非泛型方式调用泛型方法 (二)_休闲_212                            ConstructorInfo ci 
= target.GetConstructor(new Type[] { delegateType });
以非泛型方式调用泛型方法 (二)_职场_215                            
return (T) ci.Invoke(new object[] { GM });
以非泛型方式调用泛型方法 (二)_职场_14                        }

以非泛型方式调用泛型方法 (二)_职场_14                    }

以非泛型方式调用泛型方法 (二)_职场_14                }

以非泛型方式调用泛型方法 (二)_职场_14            }

以非泛型方式调用泛型方法 (二)_职场_13            
return default(T);
以非泛型方式调用泛型方法 (二)_职场_14        }

以非泛型方式调用泛型方法 (二)_职场_14    }

以非泛型方式调用泛型方法 (二)_泛型_225}

以非泛型方式调用泛型方法 (二)_职场