2008-09-15 57 views
5

C#的屬性我有一個類與一羣看起來像這樣的屬性:與重複的代碼

public string Name 
{ 
    get { return _name; } 
    set { IsDirty = true; _name = value; } 
} 

這將是一個容易得多,如果我可以依靠C#3.0產生這些後備存儲,但是有什麼辦法可以將IsDirty = true;這樣我可以寫我的屬性是這樣,仍然可以得到相同的行爲:

[MakesDirty] 
public string Name { get; set; } 
+0

看起來這是不可能的(感謝Gishu),所以我將使用CodeRush的模板。感謝您提醒我關於片段。 – 2008-09-15 15:15:52

回答

5

不是沒有寫出比原始版本更多的(奧術?)代碼(您必須使用反射來檢查屬性上的屬性,以及我沒有提到它是'較慢')..這是我可以忍受的那種重複。

MS對raising events when a property is changed的需求相同。 INotifyPropertyChanged是變更通知的重要接口。我見過的 每實現不

set 
{ 
    _name = value; 
    NotifyPropertyChanged("Name"); 
} 

如果有可能,我想弄清楚在MS那些聰明的傢伙就已經有類似的東西在地方..

3

你可以嘗試建立一個代碼段可以很容易地創建這些。

0

另一種替代方案可能是codemith等代碼生成器來自動創建屬性。如果您創建的屬性是數據庫表中的列,這將特別有用。

0

ContextBound對象。如果您創建了一個擴展上下文綁定對象的類並創建了一個context屬性,則可以攔截對此屬性所做的調用並設置IsDirty。 .NET將爲你的類創建一個代理,所有的調用都會像遠程接收器一樣。

雖然這種方法的問題是您的代理只會在外部調用時被調用。我會給你一個例子。

A級 {Foo] public int Property1 {get;設置;} public int Property2 {get {return variable;} set {Property1 = value;變量=值; }

}

當property1從另一個類調用,您的代理會如果其他類調用property2,即使集property2的將調用property1沒有代理將被調用,(代理invoked.But當你在課堂上時,不是必需的)。

這裏有很多使用contextboundobjects的示例代碼,請看它。

+0

埃米爾,這在技術上是一個解決方案 - 但是,個人認爲這不是一個好的地方來應用這個:)好的答案 - 但不能在這個問題的上下文中upvote。對不起,這個雙關語:) – Gishu 2008-09-15 15:03:35

0

我可以推薦使用Enterprise Library爲了這個目的。例如,當您輸入/退出方法時,策略應用程序塊會提供基礎結構以執行「某些事情」(某些事情=您可以自己編寫代碼)。您可以使用屬性來控制行爲。以此作爲提示,詳細說明企業庫的文檔。

0

有一個DefaultValueAttribute可以分配給一個屬性,這主要是由設計器工具使用的,所以它們可以指示屬性何時被更改,但是,它可能是一種「整齊」的方式來描述默認值對於一個財產是,因此能夠確定它是否發生了變化。

您需要使用Reflection來識別屬性更改 - 實際上並不是昂貴,除非您正在做很多!

警告:您將無法判斷某個屬性是否已從非默認值更改回默認值。

2

不,您使用自動屬性時,您無法控制實現。最好的選擇是使用模板工具,代碼片段或創建一個封裝了setter邏輯的私有SetValue>(ref T backingField,T value)。

private void SetValue<T>(ref T backingField, T value) 
{ 
    if (backingField != value) 
    { 
     backingField = value; 
     IsDirty = true; 
    } 
} 

public string Name 
{ 
    get 
    { 
     return _name; 
    } 
    set 
    { 
     SetValue(ref _name, value); 
    } 
} 
+0

但是,你必須在每個這樣的類中重複SetValue 方法。如果你把它變成一個公共的靜態/實用方法,你必須公開IsDirty狀態..不是很酷:) – Gishu 2008-09-15 15:06:09

+0

@Gishu:是的,你會在每個屬性和每個類中重複SetValue的調用。取決於你的calsses派生的方式將決定SetValue(因此IsDirty)是否公開。 – 2008-09-15 15:18:29

0

我想說,解決這個問題的最好方法是使用面向方面編程(AOP)。席勒賀蘭德做了write up on this on InfoQ。文章有點混亂,但可以遵循。 有很多不同的產品在.NET空間中執行AOP,我推薦PostSharp。

0

如果你確實使用了屬性,我相當肯定你必須通過roll your own logic來推斷它們的含義以及如何處理它們。無論使用自定義類對象,都必須有一種方法來執行這些屬性操作/檢查,最好是在實例化時。

否則,你正在尋找使用可能的事件。您仍然必須將該事件添加到每個設置的方法中,但是這樣做的好處是您不需要對每個屬性上的髒集進行硬編碼,並且可以在一個位置控制要執行的操作。這至少會引入更多的代碼重用。

3

如果您真的想這樣做,要修改代碼使用屬性所做的工作,有一些方法可以實現,它們都與AOP(面向方面​​編程)相關。查看PostSharp,這是一個後編譯器,可以在編譯後步驟中修改您的代碼。例如,您可以爲屬性設置一個自定義屬性(或方面,它是如何在AOP中調用的),它將屬性設置器中的代碼注入,將對象標記爲髒。如果你想要一些如何實現的例子,你可以看看他們的tutorials

但是要小心使用AOP,因爲使用它可能會很容易地產生更多的問題,如果您沒有正確使用它,您就試圖解決這個問題。

還有更多的AOP框架使用後編譯和一些在.Net中使用的方法攔截機制,後者與第一個相比有一些性能上的缺陷。