2011-07-14 110 views
2

我有一個類。 這個類應該有一個Content-property。目前內容的類型爲:List<IRowContent>C# - 複雜變量賦值

IRowContent是一個接口)

其他類ColumnTextContentImageContent實現接口IRowContent

我現在可以添加一些列到列表或真正的「內容」(文本或圖像)。

但您也可以添加列和文本/圖像。但是如果一行包含文本/圖像,它不應該包含其他項目。

我如何設計我的班級結構來支持這一點?

編輯:一些additionals的相關信息: 我想建立「流利的接口」佈局http://en.wikipedia.org/wiki/Fluent_interface

而且我愛迪就是爲了防止VisualStudio中的智能感知錯誤使用。

在這裏我的課程: 佈局有一個列表。

class Layout 
    { 
     //Attributes 
     public Color Background { get; set; } 
     public List<Column> Columns { get; set; } 
     public uint Margin { get; set; } 

     public Layout AddColumn(Column c) 
     { 
     return null; 
     } 

     public Layout SetColumnList(List<Column> c) 
     { 
     return null; 
     } 
    } 

該塔具有的內容(IColumnContent)的列表。該列本身來自IRowContent。

class Column : IRowContent 
    { 
     public List<IColumnContent> Content { get; private set; } 

     public Column AddToContent(IColumnContent obj) 
     { 
     return null; 
     } 

     public Column SetContent(List<IColumnContent> objs) 
     { 
     return null; 
     } 
    } 

同樣爲與IRowContent行:

class Row : IColumnContent 
    { 
     public List<IRowContent> Content { get; private set; } 

     //... 
    } 

ImageContent和的TextContent實現兩個接口:

class TextContent : IRowContent, IColumnContent 

class ImageContent : IRowContent, IColumnContent 
+0

你知道的.NET接口命名慣例? – ChaosPandion

+1

Ew,一個不帶'I'前綴的接口 - 這可能很麻煩。我可能會回答這個問題,但它看起來像Jon Skeet已經在甲板上,並且在我輸入此評論時會有一個[更好的]解決方案。 –

+0

@Brad:不,不打算捲入這一項,所以,儘管回答:) –

回答

3

如果聲明的接口

interface IRowContent 
{ 
    bool SupportsOtherChildren{ get; } 
    ... 
} 

class ImageContent : IRowContent 
{ 
    public bool SupportsOtherChildren 
    { 
     get { return false; } 
    } 
} 

class Column : IRowContent 
{ 
    public bool SupportsOtherChildren 
    { 
     get { return true; } 
    } 
} 

您可以覆蓋集合的插入和刪除的方法來支持這一行爲:

class RowContentCollection : Collection<IRowContent> 
    { 
     bool containsSingleItem = false; 
     protected override void InsertItem(int index, IRowContent item) 
     { 
      if (containsSingleItem) 
       throw new InvalidOperationException("Collection contains an item that doesnt allow other items."); 

      containsSingleItem = !item.SupportsOtherChildren; 

      base.InsertItem(index, item); 
     } 

     protected override void RemoveItem(int index) 
     { 
      if (!this[index].SupportsOtherChildren) 
       containsSingleItem = false; 

      base.RemoveItem(index); 
     } 
    } 
+0

停止我的手指也同意這種說法,收集具有內在的侷限性取代通用'名單',我也同意了界面需要更多的支持「必須站起來」的旗幟。 –

0

你可以讓你的類通用:

class Row<T : IRowContent> { 
    public List<T> Content { ... } 
} 

然後,您可以使用僅包含列的Row<Column>或僅包含文本內容的Row<TextContent>。您甚至可以擁有允許混合內容的Row<IRowContent>

如果你想有一個行只能包含文本圖像內容(但不列),添加一個interfance IRealContent : IRowContent,並有TextContentImageContent實施IRealContent。然後,Row<IRealContent>只能包含文本和圖像。

1

只是總結,並確保我理解正確:

的類應該包含列的列表。每列可以是ColumnTextContentImageContent類型的對象。所有這三個類實現RowContent接口(在我看來應該命名爲IColumnContent ...)。

如果這是正確的,你試圖強加(我不完全理解,說實話)的限制是不是一流的設計的問題,但增加的問題/刪除邏輯。我想聲明Content財產

private List<RowContent> m_internalColumns; 

public RowContent[] Columns { get { return m_internalColumns.ToArray(); }} 

,創造AddRemove方法,如以下(僞代碼):

public void Add(RowContent column) 
{ 
    if (adding column of type <typeof(column)> is allowed) 
     m_internalColumns.Add(column); 
} 

public void Remove(RowContent column) 
{ 
    m_internalColumns.Remove(column); 
} 
+0

同意,有一個通用的'名單堅持'是不會給予必要的限制。有時間製作一個自定義列表來實現自己的添加/刪除功能。 –

+0

m_internalColumns中的m代表什麼? – Bas

+0

@bas:'m _...'是一種聲明私有成員(命名約定,'m'意味着'member')的方法。 –

0

摘要的有關該問題的接口本身的細節。

public interface IRowContent 
{ 
     bool SupportsChildren { get; } 

     // other properties 
} 

我還會向Row類引入自定義添加和刪除方法,以確定添加的內容是否可以支持附加內容。

0

我可能會做的兩件事情之一。可以是:

而不是使用Row.Content.Add()添加項目,添加方法添加內容。 Row.AddContent(iRowContent content);,並把你的'邏輯'放在這個方法中,以確定是否可以添加任何項目。

或者,而不是使用列表,實現您自己的集合,其中包含IList並以包含您的邏輯的方式編寫Add()方法。