2011-07-14 11 views
2

私はクラスを持っています。 このクラスにはContentプロパティが必要です。現在のコンテンツタイプのものである:List<IRowContent>C# - 複雑な変数代入

他のクラスColumnTextContentImageContentインターフェイスIRowContentを実装(IRowContentインターフェイスです)。

ここで、リストに実際の「コンテンツ」(テキストまたはイメージ)を追加できます。

ただし、列とテキスト/画像を追加することもできます。しかし、行にtext/imageが含まれている場合は、別の項目を含むべきではありません。

これをサポートするためにクラス構造をどのように設計できますか?

編集:一部additionalsに関する情報: 私はhttp://en.wikipedia.org/wiki/Fluent_interface

そして、私のIDEEの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からのものです。 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; 
     } 
    } 

:あなたは、一般的なごクラスを作ることができ

class TextContent : IRowContent, IColumnContent 

class ImageContent : IRowContent, IColumnContent 
+0

.netインターフェイスの命名規則に気づいていますか? – ChaosPandion

+1

Ew、接頭辞 'I'が付いていないインターフェイス - 面倒なことがあります。そして私はおそらくこれに答えるだろうが、Jon Skeetが既にデッキに入っているように見え、このコメントを入力する頃には[良い]解決策があるだろう。 –

+0

@ブラッド:いいえ、これに関わることを計画していなかったので、先に進んで答えてください:) –

答えて

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

これに同意し、組み込みの制限付きコレクションは一般的な 'List 'に取って代わります。インターフェースは、 "must stand along"フラグをサポートするためにより多くのものを必要とする。 –

0

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

     //... 
    } 

ImageContentとのTextContentは、両方のインターフェイスを実装します次に、Row<Column>には列のみを含めることができ、Row<TextContent>にはテキストコンテンツのみを含めることができます。あなたは混合コンテンツを可能にするRow<IRowContent>を持つことさえできます。

テキストのみ画像コンテンツ(ただし、列)を含むことができ、行をしたい場合は、interfance IRealContent : IRowContentを追加し、TextContentImageContentIRealContentを実装しています。その場合、Row<IRealContent>にはテキストと画像しか含めることができません。

クラスは列のリストを含める必要があります。ただ、要約すると、私が正しくあなたを理解していることを確認するために

1

。すべての列は、タイプColumn,TextContentまたはImageContentのオブジェクトにすることができます。これら3つのクラスはすべてRowContentインターフェイス(私の意見ではIColumnContentという名前にする必要があります)を実装しています。

これが正しければ、(私が完全に理解していないが、正直言って)強制しようとしている制限は、クラス設計の問題ではなく、ロジックの追加/削除の問題です。私は

private List<RowContent> m_internalColumns; 

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

としてContentプロパティを宣言し、次の(擬似コード)のような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

合意して、一般的な' List 'に固執することは必要な制限を課しません。独自の追加/削除機能を実装するカスタムリストを作成する時間。 –

+0

m_internalColumns内のmは何を表しますか? – Bas

+0

@bas: 'm _...'はプライベートメンバーを宣言する方法です(命名規則、 'm'は' member'を意味します)。 –

0

抽象インタフェース自体に問題の詳細を。

public interface IRowContent 
{ 
     bool SupportsChildren { get; } 

     // other properties 
} 

追加するコンテンツが追加のコンテンツをサポートできるかどうかを判断するカスタムのAddメソッドとRemoveメソッドをRowクラスに導入します。

0

私はおそらく2つの物事のいずれかを実行します。

Row.Content.Add()を使用して項目を追加する代わりに、コンテンツを追加する方法をに追加します。 Row.AddContent(iRowContent content);を追加し、追加できるアイテムがあるかどうかを判断するために、そのメソッドに 'ロジック'を入れます。

または、リストを使用する代わりに、IListを含む独自のコレクションを実装し、ロジックを含む方法でAdd()メソッドを記述します。