都说Reflection的性能相当差,但是非用不可的时候也得用,下面是提高反射效率的一个办法。
要被反射调用的类都实现一个接口,调用的那个类引用这个接口,将反射得来的类都转换为这个接口,然后直接调用,没有必要所有的方法都反射。
公用的接口
代码: namespace CommonInterface
{
    /**//// <summary>
    /// 公用的接口
    /// </summary>
    public interface IFoo
    {
        string getName();
        string Name{get;}
    }
}
被反射调用的类
代码: using CommonInterface;
 
namespace ClassLibOne
{
    /**//// <summary>
    /// Class1 的摘要说明。
    /// </summary>
    public class FooOne:IFoo
    {
        public FooOne()
        {
        }
        
        public string getName()
        {
            return "FooOne";
        }
 
        public string Name
        {
            get
            {
                return "FooOne";
            }
        }
    }
}
调用者类
代码: using System;
using System.Reflection;
using CommonInterface;
 
namespace ReflectionMain
{
    /**//// <summary>
    /// Class1 的摘要说明。
    /// </summary>
    public class ReflectionMain
    {
        delegate string DgetName();
        /**//// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            //加载
            Assembly assembly = Assembly.LoadFile("D:\Project2003\BankTest\Reflection\ReflectionTest\ReflectionMain\bin\Debug\ClassLibOne.dll");
            Type type = assembly.GetType("ClassLibOne.FooOne");
            ConstructorInfo conInfo = type.GetConstructor(new Type[]{});
            object fooOne = conInfo.Invoke(new object[]{});
 
            //反射调用
            DateTime startR = DateTime.Now;
            for(int i=0;i<100000;i++)
            {
                object rtn;
                rtn = type.GetMethod("getName").Invoke(fooOne,new object[]{});
            }
            TimeSpan spanR = DateTime.Now - startR;
            Console.WriteLine("反射调用100,000次:"+spanR.ToString()); 
 
            //转换成接口后调用
            DateTime startI = DateTime.Now;
            for(int i=0;i<1000000;i++)
            {
                IFoo foo = (IFoo)fooOne;
                foo.getName();
            }
            TimeSpan spanI = DateTime.Now - startI;
            Console.WriteLine("转换成接口后调用1,000,000次:"+spanI.ToString());
 
            //用委托调用
            DateTime startDA = DateTime.Now;
            IFoo fooo = (IFoo)fooOne;
            DgetName dgn = new DgetName(fooo.getName);
            for(int i=0;i<10000;i++)
            {
                IFoo foo = (IFoo)fooOne;
                dgn += new DgetName(foo.getName);
            }
            TimeSpan spanDA = DateTime.Now - startDA;
 
            Console.WriteLine("用委托调用__添加到委托10,000:"+spanDA.ToString());
 
            DateTime startD = DateTime.Now;
            dgn();
            TimeSpan spanD = DateTime.Now - startD;
 
            Console.WriteLine("用委托调用10,000:"+spanD.ToString());
 
            Console.ReadLine();
        }
    }
}
输出结果是: