天天看點

以非泛型方式調用泛型方法

通過泛型方法定義具有特定類型意義的方法是常用的手段。但在某些特定情況下,例如在一些通用的架構中,直到運作時才能确定泛型類型參數,就必須通過非泛型方式來調用泛型方法。

假定有這樣一個方法:

以非泛型方式調用泛型方法

public   static   void  Add < T > (T obj, IList < T >  list)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

{

以非泛型方式調用泛型方法

      list.Add(obj);

以非泛型方式調用泛型方法

}

以非泛型方式調用泛型方法

如果想換成這樣調用:

以非泛型方式調用泛型方法

Add(Type type, object obj, object list);

通常的方法是這樣的:

以非泛型方式調用泛型方法

void  Add(Type type,  object  obj,  object  list)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

    MethodInfo mi = typeof(MyType).GetMethod("Add");

以非泛型方式調用泛型方法

    MethodInfo gmi = mi.MakeGenericMethod(type);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

    gmi.Invoke(new object[] 

以非泛型方式調用泛型方法

{ obj, list });

以非泛型方式調用泛型方法

當然,除了性能上的問題,這個方案是完全可行的。但是經過測試,通過這種包裝後的耗時比直接的泛型調用相差将近1000倍。是以還需要一些折中一點的方案。為此,我請教了裝配腦袋。他給出了一個非常好的方案:

先定義一個泛型包裝委托:

以非泛型方式調用泛型方法

public delegate void GM<T>(T obj, IList<T> list);

然後再定義一個非泛型包裝的接口:

以非泛型方式調用泛型方法

interface  ING

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

    void NGM(object obj, object list);

以非泛型方式調用泛型方法

然後再實作這個接口,在實作類中直接調用傳入的泛型委托:

以非泛型方式調用泛型方法

public   class  GClass < T >  : ING

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

    private GM<T> m_gmd;

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

    public GClass(GM<T> gmd)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

        m_gmd = gmd;

以非泛型方式調用泛型方法

    }

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

    INGClass 成員#region INGClass 成員

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

    public void NGM(object obj, object list)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

        m_gmd((T)obj, (IList<T>)list);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

    #endregion

以非泛型方式調用泛型方法

然後就可以非常簡單地使用已有的泛型方法來獲得一個非泛型接口實作了:

以非泛型方式調用泛型方法

static  ING GetNGC(Type genericType, Type methodType,  string  methodName)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

    MethodInfo mi = methodType.GetMethod(methodName);

以非泛型方式調用泛型方法

    MethodInfo gmi = mi.MakeGenericMethod(genericType);

以非泛型方式調用泛型方法

    Delegate gmd = Delegate.CreateDelegate(typeof(GM<>).MakeGenericType(genericType), gmi);

以非泛型方式調用泛型方法

    return Activator.CreateInstance(typeof(GClass<>).MakeGenericType(genericType), gmd) as ING;

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

通過執行所傳回接口的非泛型方法來達到調用泛型方法的目的:

以非泛型方式調用泛型方法

ING ng  =  GetNGC( typeof ( int ),  typeof (MyType),  " Add " );

以非泛型方式調用泛型方法

ng.NGM(i, list);

比對一下,耗時大約是直接泛型調用耗時的三倍。顯然這個方案是一個非常實用的方案。歸納一下,一共需要四步:

定義泛型委托;

定義非泛型接口;

實作這個接口;

通過泛型委托擷取非泛型接口的實作。

其中前兩步比較簡單,後兩部稍嫌麻煩。于是,我們再進一步實作一個通用的接口實作及其輸出。

以非泛型方式調用泛型方法

using  System;

以非泛型方式調用泛型方法

using  System.Collections.Generic;

以非泛型方式調用泛型方法

using  System.Reflection;

以非泛型方式調用泛型方法

using  System.Reflection.Emit;

以非泛型方式調用泛型方法

using  System.Text;

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

namespace  GenericMethodTest

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

    /**//// <summary>

以非泛型方式調用泛型方法

    /// 接口生成器

以非泛型方式調用泛型方法

    /// </summary>

以非泛型方式調用泛型方法

    internal static class InterfaceGenerator

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

        private static Random _Random = new Random();

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

        private static char GetRandomLetter()

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            int i = (_Random.Next() % 26) + 97;

以非泛型方式調用泛型方法

            byte[] b = BitConverter.GetBytes(i);

以非泛型方式調用泛型方法

            return BitConverter.ToChar(b, 0);

以非泛型方式調用泛型方法

        }

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

        private static string GetRandomString(int n)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            char[] chars = new char[n];

以非泛型方式調用泛型方法

            for (int i = 0; i < n; i++)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                chars[i] = GetRandomLetter();

以非泛型方式調用泛型方法

            }

以非泛型方式調用泛型方法

            return new string(chars);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

        private static void LoadArg(ILGenerator gen, int index)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            switch (index)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                case 0:

以非泛型方式調用泛型方法

                    gen.Emit(OpCodes.Ldarg_0);

以非泛型方式調用泛型方法

                    break;

以非泛型方式調用泛型方法

                case 1:

以非泛型方式調用泛型方法

                    gen.Emit(OpCodes.Ldarg_1);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                case 2:

以非泛型方式調用泛型方法

                    gen.Emit(OpCodes.Ldarg_2);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                case 3:

以非泛型方式調用泛型方法

                    gen.Emit(OpCodes.Ldarg_3);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                default:

以非泛型方式調用泛型方法

                    if (index < 128)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                        gen.Emit(OpCodes.Ldarg_S, index);

以非泛型方式調用泛型方法

                    }

以非泛型方式調用泛型方法

                    else

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                        gen.Emit(OpCodes.Ldarg, index);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

        public static T GetInterface<T>(Delegate GM)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            if (typeof(T).IsInterface)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                Type delegateType = GM.GetType();

以非泛型方式調用泛型方法

                if (delegateType.IsGenericType)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                    if (typeof(MulticastDelegate).IsAssignableFrom(delegateType.GetGenericTypeDefinition()))

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                        Type[] genericTypes = delegateType.GetGenericArguments();

以非泛型方式調用泛型方法

                        if (genericTypes.Length == 1)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                            Type genericType = genericTypes[0];

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

#if SAVE

以非泛型方式調用泛型方法

                            string theFilename = "InterfaceGenerator.Attachments.dll";

以非泛型方式調用泛型方法

#endif

以非泛型方式調用泛型方法

                            AssemblyName aname = new AssemblyName();

以非泛型方式調用泛型方法

                            aname.Name = string.Format("InterfaceGenerator.Attachments.{0}", GetRandomString(16));

以非泛型方式調用泛型方法

                            aname.Version = new Version("2.0.0.0");

以非泛型方式調用泛型方法

                            AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(aname,

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

 AssemblyBuilderAccess.RunAndSave

以非泛型方式調用泛型方法

#else

以非泛型方式調用泛型方法

 AssemblyBuilderAccess.Run

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

);

以非泛型方式調用泛型方法

                            ModuleBuilder module = assembly.DefineDynamicModule(GetRandomString(8)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

, theFilename

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                            TypeBuilder builder = module.DefineType(GetRandomString(16), TypeAttributes.Sealed | TypeAttributes.Class | TypeAttributes.Public);

以非泛型方式調用泛型方法

                            builder.AddInterfaceImplementation(typeof(T));

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                            // 先定義成員域,用于儲存傳入的委托。

以非泛型方式調用泛型方法

                            FieldBuilder field = builder.DefineField(GetRandomString(8), delegateType, FieldAttributes.Private);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                            // 定義構造器。

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                            ConstructorBuilder ctor = builder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] 

以非泛型方式調用泛型方法

{ delegateType });

以非泛型方式調用泛型方法

                            ILGenerator ctorGen = ctor.GetILGenerator();

以非泛型方式調用泛型方法

                            ctorGen.Emit(OpCodes.Ldarg_0);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                            ctorGen.Emit(OpCodes.Call, typeof(object).GetConstructor(new Type[] 

以非泛型方式調用泛型方法

{ }));

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                            ctorGen.Emit(OpCodes.Ldarg_1);

以非泛型方式調用泛型方法

                            ctorGen.Emit(OpCodes.Stfld, field);

以非泛型方式調用泛型方法

                            ctorGen.Emit(OpCodes.Ret);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                            // 雖然這麼寫,但事實上接口隻有一個方法。

以非泛型方式調用泛型方法

                            foreach (MethodInfo bmi in typeof(T).GetMethods())

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                                ParameterInfo[] paramInfos = bmi.GetParameters();

以非泛型方式調用泛型方法

                                Type[] argTypes = new Type[paramInfos.Length];

以非泛型方式調用泛型方法

                                int i = 0;

以非泛型方式調用泛型方法

                                foreach (ParameterInfo pi in paramInfos)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                                    argTypes[i++] = pi.ParameterType;

以非泛型方式調用泛型方法

                                }

以非泛型方式調用泛型方法

                                MethodAttributes attributes = MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.ReuseSlot | MethodAttributes.Public;

以非泛型方式調用泛型方法

                                MethodBuilder method = builder.DefineMethod(bmi.Name, attributes, bmi.ReturnType, argTypes);

以非泛型方式調用泛型方法

                                builder.DefineMethodOverride(method, bmi);

以非泛型方式調用泛型方法

                                MethodInfo dmi = delegateType.GetMethod("Invoke");

以非泛型方式調用泛型方法

                                ILGenerator methodGen = method.GetILGenerator();

以非泛型方式調用泛型方法

                                bool hasReturn = false;

以非泛型方式調用泛型方法

                                if (dmi.ReturnType != typeof(void))

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                                    methodGen.DeclareLocal(dmi.ReturnType);

以非泛型方式調用泛型方法

                                    hasReturn = true;

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                                methodGen.Emit(OpCodes.Ldarg_0);

以非泛型方式調用泛型方法

                                methodGen.Emit(OpCodes.Ldfld, field);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                                i = 0;

以非泛型方式調用泛型方法

                                foreach (ParameterInfo pi in dmi.GetParameters())

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                                    LoadArg(methodGen, i + 1);

以非泛型方式調用泛型方法

                                    if (!pi.ParameterType.IsAssignableFrom(argTypes[i]))

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                                        if (argTypes[i].IsClass)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                                            methodGen.Emit(OpCodes.Castclass, pi.ParameterType);

以非泛型方式調用泛型方法

                                        }

以非泛型方式調用泛型方法

                                        else

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                                            methodGen.Emit(OpCodes.Unbox, pi.ParameterType);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                                    }

以非泛型方式調用泛型方法

                                    i++;

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                                methodGen.Emit(OpCodes.Callvirt, dmi);

以非泛型方式調用泛型方法

                                if (hasReturn)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                                    methodGen.Emit(OpCodes.Stloc_0);

以非泛型方式調用泛型方法

                                    methodGen.Emit(OpCodes.Ldloc_0);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                                methodGen.Emit(OpCodes.Ret);

以非泛型方式調用泛型方法

                            }

以非泛型方式調用泛型方法

                            Type target = builder.CreateType();

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                            assembly.Save(theFilename);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                            ConstructorInfo ci = target.GetConstructor(new Type[] 

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                            return (T) ci.Invoke(new object[] 

以非泛型方式調用泛型方法

{ GM });

以非泛型方式調用泛型方法

                        }

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                }

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            return default(T);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

結論:

以下是測試代碼:

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

    // 為泛型方法定義的委托

以非泛型方式調用泛型方法

    public delegate void GM<T>(T obj, IList<T> list);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

    // 為非泛型方法定義的接口

以非泛型方式調用泛型方法

    public interface ING

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

        void NGM(object obj, object list);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

    class Program

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

        static void Main(string[] args)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            List<int> list = new List<int>();

以非泛型方式調用泛型方法

            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();

以非泛型方式調用泛型方法

            watch.Reset();

以非泛型方式調用泛型方法

            watch.Start();

以非泛型方式調用泛型方法

            for (int i = 0; i < 1000000; i++)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                list.Add(i);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            watch.Stop();

以非泛型方式調用泛型方法

            long l1 = watch.ElapsedMilliseconds;

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            GM<int> gm = new GM<int>(Program.Add);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                gm(i, list);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            long l2 = watch.ElapsedMilliseconds;

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            MethodInfo mi = typeof(Program).GetMethod("Add");

以非泛型方式調用泛型方法

            MethodInfo gmi = mi.MakeGenericMethod(typeof(int));

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                gmi.Invoke(null, new object[] 

以非泛型方式調用泛型方法

{ i, list });

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            long l3 = watch.ElapsedMilliseconds;

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            ING ng1 = GetNGC(typeof(int), typeof(Program), "Add");

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                ng1.NGM(i, list);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            long l4 = watch.ElapsedMilliseconds;

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            ING ng2 = InterfaceGenerator.GetInterface<ING>(new GM<int>(Program.Add));

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

                ng2.NGM(i, list);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            long l5 = watch.ElapsedMilliseconds;

以非泛型方式調用泛型方法

            Console.WriteLine("{0}/n{1} vs {2} vs {3} vs {4} vs {5}", list.Count, l1, l2, l3, l4, l5);

以非泛型方式調用泛型方法

            Console.ReadLine();

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

        public static void Add<T>(T obj, IList<T> list)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            list.Add(obj);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

        static ING GetNGC(Type genericType, Type methodType, string methodName)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            MethodInfo mi = methodType.GetMethod(methodName);

以非泛型方式調用泛型方法

            MethodInfo gmi = mi.MakeGenericMethod(genericType);

以非泛型方式調用泛型方法

            Delegate gmd = Delegate.CreateDelegate(typeof(GM<>).MakeGenericType(genericType), gmi);

以非泛型方式調用泛型方法

            return Activator.CreateInstance(typeof(GClass<>).MakeGenericType(genericType), gmd) as ING;

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

    public class GClass<T> : ING

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

        private GM<T> m_gmd;

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

        public GClass(GM<T> gmd)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            m_gmd = gmd;

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

        INGClass 成員#region INGClass 成員

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

        public void NGM(object obj, object list)

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

            m_gmd((T)obj, (IList<T>)list);

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

        #endregion

以非泛型方式調用泛型方法
以非泛型方式調用泛型方法
以非泛型方式調用泛型方法

測試結果:

方案

耗時

比對

其他優點

直接調用

18

1

不通用

泛型委托包裝

43

2.39

反射

16538

918.78

通用,不需額外定義

非泛型接口包裝

60

3.33

通用,需要額外定義并實作

動态生成的非泛型接口包裝

72

4

通用,需要額外定義