2012-07-03 24 views
8

我有一個類別/文件樹結構。這兩個類別和文件都可以有父項,所以我從具有Parent屬性的公共基類中派生它們。由於所有的父母顯然總是類別(文件不能是父類),因此使節點的Parent屬性成爲CategoryNode類型似乎是有意義的。在基本類型中引用派生類型是否是錯誤的形式?

對於引用派生類的基類,它是不好的形式嗎?如果是這樣,爲什麼?如果是這樣,什麼是更好的方式來構造這個?

class Node { 
    public CategoryNode Parent {get; set;} 
} 

class File : Node { 
    ... 
} 

class CategoryNode : Node { 
    ... 
} 
+0

AFAIU,它們都爲共享屬性擴展相同的基類,所以爲什麼不使用遞歸引用自己的單類?有額外的屬性來區分它們。 –

+0

是的,這是不好的。導致循環依賴。 Base不應該知道Derived的任何內容。 – Tilak

+0

@Furqan,File節點不需要CategoryNode所具有的額外內容,例如子節點,所以我不認爲它應該從CategoryNode派生。 – Kelsie

回答

4

如果屬性Parent實際上是所有後代的共同屬性,並且始終是類別CategoryNode,這不是問題。從語義上講,這是正確的,並且在技術上我認爲它只要保持在同一個庫中就是正確的(避免循環引用)。

// BAD CODE 
if(myProp is subclassA) 
{ ... 
} 
else if (myProp is syubclassB) 
{ ... 
} 

此代碼是不好的,因爲你失去繼承的優勢:當你寫這樣的代碼

這可能是一個問題。

即使在.Net框架中也有這樣的構造。我想到的第一個例子是XObject.Parent屬性。

XElement繼承XObject,而XObject發佈XElement類型的屬性。與您的摘錄相同。

1

基類不應該知道誰來自它。

如果你有這種情況,你可能不想繼承。你應該只使用某種形式的耦合。

File和CategoryNode應該在你的情況下持有一個Node成員。

+0

我不能同意你的看法。如果Parent始終是CategoryNode呢?在基類中可能存在一些問題,如if(myProp is subclassA){...} else if(myProper is syubclassB){...}'。這樣的事情很骯髒。但不是OP建議的樣本 –

+0

但事實並非如此。我們只是看到父母可以是File,它與CategoryNode沒有任何關聯。 –

+0

OP說'文件不能是父母' –

1

其他選項將更改類層次結構以使CategoryNode成爲根類(a),或者將屬性類型更改爲節點(b)。

這兩種可能性都不好: (a)文件將具有它不需要的所有功能CategoryNode。 (b)它會隱藏對象類型(總是CategoryNode)。這可能會導致代碼中其他地方出現無效的轉換錯誤。例如,如果你忘記了總有一個CategoryNode實例。考慮到這一點,我相信當前的代碼是可以的。

7

你可以這樣做......

interface IParent { 
    ... 
} 

class Node { 
    public IParent Parent {get; set;} 
} 

class File : Node { 
    ... 
} 

class CategoryNode : Node, IParent { 
    ... 
} 

這樣,你不需要引用派生類對象的基類,再加上,你是在什麼實際上可以成爲父母更靈活,以防在稍後的時間點獲得其他對象類型。而且,任何與父代相關的功能都可以在該接口中聲明。

+0

也許你可以在界面中添加:'IEnumerable ChildNodes'? –

+0

@Steve這是一個設計問題。當然這是可能的,但是我不會再調用接口'IParent'。 OP想要引用一個父對象,而不是一個(列表)子對象。對我來說,看起來奇怪的是,有一些類似IEnumerable Children的聲明,並且我個人會將接口重命名爲更適合的東西......如果您有一個包含許多這種命名風格例子的大型項目,那麼您'重新在地獄之路恕我直言...... – takrl

+0

你是對的......這可能導致混亂 –

相關問題