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
表达式树无论如何都不能内联,因为它们是表达式的表示(抽象语法树)而不是表达式本身。
委托,即使它们可以内联,仍然会在它们的属性中携带关于被调用的方法和目标的数据。