属性/方法内联及其对反射的影响

本文关键字:反射的 影响 方法 属性 | 更新日期: 2023-09-27 18:01:58

Valentin Kuzub评论了我对SO的一个问题的回答,他认为通过JIT编译器内联属性会导致反射停止工作。

情况如下:

class Foo
{
    public string Bar { get; set; }
    public void Fuzz<T>(Expression<Func<T>> lambda)
    {
    }
}
Fuzz(x => x.Bar);

Fuzz函数接受lambda表达式并使用反射来查找属性。这是HtmlHelper扩展中MVC的一种常见做法。

我认为即使Bar属性内联,反射也不会停止工作,因为它是对Bar的调用,将被内联,typeof(Foo).GetProperty("Bar")仍将返回有效的PropertyInfo

你能确认一下吗?还是我对方法内联的理解有误?

属性/方法内联及其对反射的影响

JIT编译器在运行时操作,它不能重写存储在程序集中的元数据信息。反射读取程序集以访问此元数据。所以jit编译器对反射没有影响。

编辑:实际上,c#编译器在编译过程中有几个地方会"内联"一些信息。例如,常量、枚举和默认参数是"内联的",所以你不能在反射期间访问它们。但这肯定与你的具体情况无关。

是的,当我考虑更多的时候,我想内联属性可能失败的唯一方法是INotifyPropertyChanged接口正确的工作将是如果你使用基于反射的方法,如

public Count
{
get {return m_Count;}
 set { m_Count=value;
      GetCurrentPropertyNameUsingReflectionAndNotifyItChanged();}
}

如果像你建议的那样使用,元数据确实存在于程序集中,属性名将成功地从那里获取。

让我们都在思考

我个人同意@Sergey:

考虑到内联发生在JIT编译器端,但是之前生成的元数据,它应该不会以任何方式影响反射。顺便说一下,好问题,喜欢+1

表达式树无论如何都不能内联,因为它们是表达式的表示(抽象语法树)而不是表达式本身。

委托,即使它们可以内联,仍然会在它们的属性中携带关于被调用的方法和目标的数据。