【问题标题】:Is some reflection code optimized at compile time?是否在编译时优化了一些反射代码?
【发布时间】:2025-12-17 16:10:02
【问题描述】:

我认为一些使用反射的代码可以在编译时进行优化(我不确定我们是否可以称之为优化)。

  • 例如System.Reflection.MethodInfo.GetCurrentMethod在同一个方法中调用时总是返回同一个值。

  • 另外,使用类名表示的常量字符串访问类信息没有理由在运行时完成。

我已经对其进行了测试,结果显示带有反射的代码比不带反射的代码慢大约 300 倍。

是否有任何编译选项可以实现我想要的功能?

【问题讨论】:

  • 看看this document关于反射性能。
  • 您询问的内容与呼叫者信息属性 (msdn.microsoft.com/en-us/library/hh534540(v=vs.110).aspx) 类似。不幸的是,当前方法信息似乎没有等效项,因此您最好的选择是简单地缓存 GetCurrentMethod 返回值。
  • 我想不出一个具体案例,例如 1,但对于第二个,信息肯定会发生变化(例如,如果您更新托管类的 DLL)
  • 你完全忽略了this。内联优化使 GetCurrentMethod() 返回其他内容。使用字符串的唯一一点是您知道它可能是什么类。编译器当然也不会。当然,用反射替换需要纳秒的代码(例如方法调用)不可避免地会慢很多。

标签: c# optimization reflection compile-time


【解决方案1】:

.net 中的反射确实非常缓慢。对此无能为力。

另一方面,可能适合您使用“fasterflect”http://fasterflect.codeplex.com/,它实现了内置 .net 反射的多个功能并提高了性能。

【讨论】:

    【解决方案2】:

    所有反射都可以被缓存并执行一次。我建议它保持性能和可扩展性。 (以静态构造函数为例,评估静态字段)

    getcurrent...thing 之类的方法是一个懒惰的快捷方式代码。你知道你在哪里......你可以将你的方法信息保存在静态私有字段中以使用它们。

    【讨论】:

      【解决方案3】:

      对于System.Reflection.MethodInfo.GetCurrentMethod 的情况。这通常用于获取当前方法调用的名称。

      如果这是用例

      public void Foo()
      {
          var method = System.Reflection.MethodInfo.GetCurrentMethod();
          Log.Log(string.Format("I is inside of {0}", method.Name));
      }
      

      那么你应该把它替换为

      public static MemberName([CallerMemberName] memberName = null)
      {
          return memberName;
      }
      
      public void Foo()
      {
          Log.Log(string.Format("I is inside of {0}", MemberName()));
      }
      

      【讨论】: