为什么通过接口通过反射调用方法要快得多

时间:2011-10-30 21:13:51

标签: c# reflection interface

为什么通过反射调用方法比创建一个接口然后通过反射调用它要慢得多。第一个版本显示了另一个版本显示增强方式的繁琐方式??

 // first version
  class A
    {
        public void fn()
        { 
        }
    }
  void Main(String[]x)
  {
        Type type = typeof(A);
        object obj = Activator.CreateInstance(type);
        type.InvokeMember("fn", BindingFlags.Public, null, obj, null);
  }

  //second verison
   interface IA
    {
        void fn();
    }

    class A :IA
    {
        public void fn()
        {
        }
    }

 void Main(String []x)
 {
        Type type = typeof(A);
        IA obj =(IA) Activator.CreateInstance(type);
        obj.fn();
 }

2 个答案:

答案 0 :(得分:6)

基于反射的方法调用非常慢,因为您需要在运行时执行成员查找和参数绑定等操作。

相反,接口方法使用vtable通过常规callvirt指令调用。

答案 1 :(得分:0)

对于苹果与苹果的比较,调用Type.GetConstructor获取ConstructorInfo对象并调用它来创建对象。然后,您可以保留ConstructorInfo并重用。相比之下,Activator非常慢。

回答关于反思方式如何运作的问题:

Activator在已加载程序集的元数据中搜索与您指定的类型名称匹配的类型名称。然后它搜索类似于Type.GetConstructor的构造函数,该构造函数返回一个ConstructorInfo。它调用该构造函数并返回该对象。

然后,当您调用Type.InvokeMember时,您再次使用反射,查询类的元数据以查找匹配的方法签名。这将作为MethodInfo返回,然后调用它。

反射中的艰苦工作不是调用本身,而是元数据搜索类型,构造函数和方法。这就是为什么我说你可以通过重用ConstructorInfo和MethodInfo对象对反射对象进行相对高性能的方法调用。您会发现重复调用MethodInfo.Invoke比Type.InvokeMember

快得多