2011-07-14 76 views
9

影響我的answer就因此問題之一是由瓦倫丁Kuzub,誰認爲,通過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工作。

你能否確認這個,請還是我的方法內聯的理解是錯誤的?

+0

順便說一句我發現這個有趣的文章,顯示不使用lambda在INotifyPropertyChange實現中的其他原因http://blog.quantumbitdesigns.com/2010/01/26/mvvm-lambda-vs-inotifypropertychanged-vs-dependencyobject/ –

回答

3

JIT編譯器操作在運行時,它不能重寫存儲在組件的元數據信息。反射讀取程序集以訪問此元數據。所以JIT編譯器對反射沒有影響。

編輯: 其實有幾個地方在C#編譯器本身「內聯」的一些編譯過程中的信息。例如,常量,枚舉和默認參數是「內聯」的,因此您在反射期間無法訪問它們。但它絕對不涉及你的具體情況。

+0

什麼你的意思是默認屬性? – leppie

+0

我的意思是默認參數,對不起。我編輯了我的答案。 –

+0

您可以將'enums'添加到列表中。 –

0

我個人@Sergey同意:

考慮到內聯發生在JIT編譯器的一面,但在此之前生成的元數據,以任何方式,它不應該反思inpact。順便說一句,好問,喜歡它+1

1

呀,當我想它更我猜只有這樣,內聯特性可能會失敗INotifyPropertyChanged接口正確的工作是,如果你使用與用於像

public Count 
{ 
get {return m_Count;} 
set { m_Count=value; 
     GetCurrentPropertyNameUsingReflectionAndNotifyItChanged();} 
} 
的反映爲基礎的方法

如果使用像你所建議的那樣確實元數據存在於程序集中,並且屬性名稱將從那裏成功取出。

雖然得到了我們兩個的想法。

+0

即使在這種情況下,我仍然認爲它會起作用。 –

+0

究竟如何?方法將不會從屬性中調用,而是從使用屬性的方法中調用,並且結果名稱不會是Count,但有些不同(最有可能是方法名稱,而不是屬性名稱) –

+0

您的方法'GetCurrentPropertyNameUsingReflectionAndNotifyItChanged'分析調用堆棧? –

0

無論如何,表達式樹不能被內聯,因爲它們是表達式(抽象語法樹)的表示而不是表達式本身。

即使可以內聯代表,代表仍將攜帶有關在其屬性中調用的方法和目標的數據。