2010-07-31 52 views
4

我在我的項目中得到了一個要求,爲某個類添加另一個屬性。 現在我想避免改變班級,因爲我覺得它不應該知道他有這個屬性(這個屬性只在這個項目的上下文中有意義)。添加屬性而不觸及類? (不是繼承)

我想做到這一點的樣子(請批評這一點,因爲我想知道是否有這樣做的更簡單的方法)

  1. 添加有我的類的對象之間的映射一個新的單例類和我想添加的屬性的類型
  2. 在此類中添加一個擴展方法(擴展屬性?)來訪問映射並獲取屬性。

有沒有更簡單的選擇? 這只是不必要的複雜性?也許我應該只爲我的班級添加一個新的屬性?

謝謝!

+0

作爲丹科比寫道,它的情況並不少見做這樣的事情,它有很多不錯的優勢。我想創建一個get和一組-ExtensionMethod你的類型(擴展的屬性不存在),並保存在一個靜態的哈希表(詞典)在您的對象是哈希表中的鍵的值。這樣做的缺點是,你沒有屬性。如果你想擁有這個,你必須採取另一種解決方案(例如複合)。 – HCL 2010-07-31 14:14:51

回答

4

您所描述的設計實際上是Microsoft用來實現DependencyProperty系統的設計,特別是Attached Properties,儘管在更大的綁定框架環境中。這就是說,使用帶有「附加」數據字典是一個非常典型的解決方案時,您需要標記加上額外的內容一類用於特殊用途,但不希望修改類。

0

擴展方法是有意義的,它也相對簡單。

[visibility] [type] [methodName](this [class to extend] c, ... more args if necessary) 
{ 
.... 
} 
+0

但靜態擴展方法不起作用像一個類屬性。 – 2010-07-31 13:50:50

+0

擴展方法是靜態的,而且必須是一個靜態類的成員。這限制了他們掌握任何形式的國家信息的能力;通常最好的做法是將擴展方法視爲無狀態(即它們不能像屬性一樣)。 – 2010-07-31 13:52:03

2

爲什麼說「不繼承」?當然,如果你不想改變原來的類,這樣做的方式是繼承原始類,然後將你的屬性添加到派生類中?

順便說一句,只有擴展方法,而不是屬性,所以你不能通過屬性來做到這一點。

+1

我可以想象很多情況下,繼承是不可能或不meaningfull,因爲事實對象創建不能(例如用一些奧姆斯工作時)的影響。構圖通常是一種選擇。 – HCL 2010-07-31 13:49:21

0

添加一個屬性不會破壞該類與現有客戶端的交互,所以看起來似乎是「最簡單」的方法。

雖然更重要的是新財產的功能。它在邏輯上是現有班級的一部分嗎?改變班級。如果不是,那麼擴展方法可能更可取,但問題將成爲擴展方法的可見性和客戶端的範圍。

一如既往,複雜性是敵人。在這種情況下,聽起來好像單身人士是一個非常複雜的解決方案,並且擴展方法是碰碰運氣,取決於範圍和可見性問題。改變班級最簡單,並且可能會使得長期維護更容易。

更新:請注意,擴展方法是靜態的,這使得擴展方法很難保存任何時間的數據,因爲屬性會被檢測到。

第二次更新:如果您有權訪問該類的源代碼,請考慮將其作爲一個部分類,並將您的新屬性放在單獨的文件中,但屬於同一部分類的一部分。這使它與班級的主體保持分離,以便維護,並且可以與大多數ORM一起使用。但是,局部類成員必須在單個程序集中才有限制。

2

我會建議DECORATOR模式。我知道你說你不想使用繼承,但有時候這樣做更清潔。該模式只使用繼承來定義接口。

0

定義一個空的值與他們的屬性(而該物業具有意義,只是爲這個項目)

您的主要問題是,你不想改變類本身,因爲這一要求只1個項目(建設),我想你正在考慮SOLID原理作爲,這些原則之一是OCP(開放 - 封閉原則),也就是

你的實體必須對擴展開放 對修改關閉