2012-05-05 105 views
0

我已經看到了這樣做的各種方法,包括反射,組件模型類型描述符,表達式樹和方面,但我仍不確定下面的代碼是否使用.Net實現了以下所有目標4.0或更高版本:獲取PropertyInfo名稱和值

  1. 類型安全,重構友好(沒有魔法字符串),並通過多次調用
  2. 可讀
  3. 最大限度地提高性能提供一個屬性
  4. 的名稱提供的屬性值

代碼如何改進?

protected void NotifyOfPropertyChanging<TProperty>(Expression<Func<TProperty>> property) { 
    var memberExpression = (MemberExpression)property.Body; 
    var prop = (PropertyInfo) memberExpression.Member; 

    var propertyName = prop.Name; 
    var value = prop.GetValue(this, null); 

    // fire INPC using propertyName 
    // use value and name to do IsDirty checking 
} 

回答

1

可能通過編譯表達式樹並將其緩存以供將來使用,而不是每次調用GetValue都可以提高性能。但是,只有當前實現導致瓶頸時才應該進行這種優化。

void NotifyOfPropertyChanging<TProperty>(Expression<Func<TProperty>> property) 
{ 
    var memberExpression = (MemberExpression) property.Body; 
    var prop = (PropertyInfo) memberExpression.Member; 

    Func<TProperty> accessor; 
    if (!TypedAccessorCache<TProperty>.Cache.TryGetValue(prop, out accessor)) 
    { 
     accessor = property.Compile(); 
     TypedAccessorCache<TProperty>.Cache[prop] = accessor; 
    } 
    var value = accessor(); 

    // ... 
} 

static class TypedAccessorCache<TProperty> 
{ 
    public static readonly IDictionary<PropertyInfo, Func<TProperty>> Cache = 
     new Dictionary<PropertyInfo, Func<TProperty>>(); 
} 

注意我已經使用了泛型靜態類型來保存緩存字典實例。這是爲每種不同的屬性類型有效創建單獨的類型化緩存的簡便方法。

0

這是一個很長的故事,我想現在還沒有比其他人更好的方法。我認爲表達式在大多數通常的業務場景中不會產生性能瓶頸(如果需要,可以優化一小段需要更快通知的代碼),所以這種方法應該沒問題。

請記住,創建表達式樹要花費更多的時間來解析它,所以請確保您只做一次(即使用靜態類級表達式變量)。但是,在這種情況下,您的模型代碼會變得有點臃腫。

我個人更喜歡使用基於字符串的INPC處理。 ReSharper在重構時可以很好地與字符串一起工作,所以我可以稱它比較安全。據我所知,這是最快的方法。使用VS或ReSharper片段,您可以輕鬆地在幾個按鍵中編寫屬性。

關於屬性值 - 它不用於既不INotifyPropertyChanging也不由INotifyPropertyChanged的接口。你爲什麼需要它?

+0

用於IsDirty檢查;如果該值不同於緩存值快照,則比我的對象IsDirty。乾杯 – Berryl