9

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 表达式并使用反射来查找属性。这是 MVC 在HtmlHelper扩展中的常见做法。

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

您能否确认一下,或者我对方法内联的理解是错误的?

4

4 回答 4

3

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

编辑:实际上有几个地方 C# 编译器本身在编译期间“内联”了一些信息。例如,常量、枚举和默认参数是“内联的”,因此您无法在反射期间访问它们。但这绝对与您的特定情况无关。

于 2011-07-14T10:44:59.753 回答
1

是的,当我更多地考虑它时,我想只有内联属性可能会失败的方法 INotifyPropertyChanged 接口正确的工作是如果您使用基于反射的方法,例如

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

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

让我们俩都在思考。

于 2011-07-14T11:00:19.280 回答
0

我个人同意@Sergey:

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

于 2011-07-14T10:48:50.160 回答
0

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

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

于 2011-07-14T11:22:12.880 回答