2009-11-25 64 views
0

我相信有一個聰明的方法來處理這個問題,但我無法正確理解它。這裏是場景:將屬性添加到基類的設計模式

我有一個基類約30屬性。假設我有一個名爲Type的類。對於這個類的實例子集,我想根據Type屬性添加更多的屬性。在這種情況下,當我創建對象時,我可以創建包含這些額外屬性的基類的子類。我的問題是,用戶可以基於組合框更改類型,我需要能夠將其轉換回基類或將其更改爲具有不同子集的其他屬性的完全不同的子類。希望這清楚地表明。有關如何處理此問題的任何建議?

注意:這是一個棕色領域的應用程序,所以雖然屬性包的想法很吸引人,但如果沒有重大的痛苦也是不可能的。

回答

0

謝謝大家的回答。最後我發現這篇文章:"Using reflection to copy base class properties"

我改編了這篇文章,並以此作爲我的工作解決方案。 (在我的例子中,我做了一個所謂的基類,並有從中獲取的一對夫婦類):

Private Shared Sub CopyBaseProperties(ByVal pSource As Base, ByVal pDestination As Base) 

     Dim fields() As FieldInfo = GetType(Base).GetFields(BindingFlags.NonPublic Or BindingFlags.Public Or BindingFlags.Instance) 
     For Each tmpField As FieldInfo In fields 
     tmpField.SetValue(pDestination, tmpField.GetValue(pSource)) 
     Next 

    End Sub 
2

只要有屬性的列表...

List<Properties> MyProps; 

,並適當地添加到它。

2

如果您從非常修改factory pattern開始,您可能會這樣做。

我會創建一個基類,並且每當Type屬性因用戶輸入而改變時,factory-ish類(我會稱他爲Bob)負責返回指定類型的類。你會打電話給Bob,傳入類型和當前對象,Bob將返回特定的子類型。

例如:

public class MyBase 
{ 
    public string Type { get; set; } 
    public string CommonProperty { get; set; } 
} 

public class ExtendedClass : MyBase 
{ 
    public string ExtraProperty { get; set; } 
} 

public static class MyNotFactory 
{ 
    public static MyBase Create(MyBase baseObject) 
    { 
     switch (baseObject.Type) 
     { 
      case "Extended": 
       return baseObject as ExtendedClass; 
       break; 
      default: 
       return baseObject; 
       break; 
     } 
    } 
} 

(注:我沒有檢查的代碼)

編輯:你知道......這是不是一個真正的工廠模式,在所有的,現在我把它在代碼...我已經改名的東西。

+1

在你的榜樣,創建沒有做任何事情,除了在任何一個開關的情況下返回其輸入。 – Josh 2009-11-25 23:29:08

+0

在第一個case語句中,它應該返回一個ExtendedClass類型的對象。第二,它應該返回一個MyBase類型的對象。 – Damovisa 2009-11-25 23:50:53

+0

但是你是對的 - 你必須檢查實際的返回類型來解決這個問題。 – Damovisa 2009-11-25 23:52:43

1

我喜歡設計模式,就像下一個傢伙一樣多,但我認爲你在這裏看到的只是普通的舊的.NET繼承和一點反思。

我創建的傳承層次,你認爲合適,使用普通的傳承,然後看看Activator.CreateInstance(或基類中的靜態工廠方法)來創建對象的實例。

+0

我確實有一個工廠來創建對象,如果它們已經存在的話,我猜我丟失了什麼,一旦對象已經創建並且它們改變了類型。在這種情況下,你是否傳入當前對象並克隆基類道具? – Codezy 2009-11-25 23:23:03

+0

您可以,或者您可以使用屬性包類型的對象來支持該對象的屬性。你可能想要考慮的一種設計模式是備忘錄,這只是一種序列化方法。如果您的所有屬性都位於字典(字符串,字符串)或更專用的屬性包類中,則可以輕鬆地將狀態從一個實例傳遞到另一個實例。 – Josh 2009-11-25 23:25:32

+0

其實應該說Dictionary(Of String,Object) – Josh 2009-11-25 23:26:08

0

在.Net(以及其他強類型,靜態語言)中,一旦實例化了一個類的實例,則無法將該實例更改爲不同的類型。

的唯一方法「改變類型」是一個兼容類型的不同實例分配給可變(如果變量將接受實施Foo和類型Foo1和foo2的都實現類型/延伸的Foo然後一個實例可以分配給變量

如果您希望在此轉換中保留一些狀態,您可以爲一個對象的一個​​實例定義一個通用方法,以從另一個兼容實例中複製所有相關值(可能通過反射if字段/屬性具有相同的類型和名稱),或者通過委託共享子部分變得容易,但是這是一種危險的做法,除非你的設計被構造爲不關心,否則n類型不是不可改變的。

你的問題可疑聽起來像是你將喜歡有以下幾點:

class FooWithAdOns 
{ 
    int Blah { get; set;} 
    int Wibble { get; set } 
    Type AddOn { get; set; } 
    /* if AddOn type is AddOnX */ 
    int X { get; set; } 
    /* if AddOn type is AddOnY */ 
    int Y { get; set; } 
} 

class AddOnX 
{ 
    int X { get; set;} 
} 


class AddOnY 
{ 
    int Y { get; set;} 
} 

是X的存在/ Y上FooWithAddOn是動態的。

有兩種方法可以實現這一點,現在有一種可能,但僅限於基於使用諸如ITypedList之類的反射的UI交互。 另一個更強大,但基於動態分派的c#4.0功能,其中方法/屬性的名稱在運行時計算出來。

如果你只是通過類似PropertyGrid的UI進行交互,那麼第一種方法將工作,只要每次你「屬性列表」更改你重建屬性網格,後者將完美的代碼工作,但是對於UI代碼,您需要編寫一個封裝程序,該封裝程序能夠完成ITypedList所做的大量工作,以將當前的「虛假屬性」暴露給反射式用戶界面。