C# - 复杂的变量赋值

时间:2011-07-14 13:45:18

标签: c# class list interface

我有一个班级Row。 该类应具有Content-property。目前内容类型为:List<IRowContent>

IRowContent是一个界面)

其他类ColumnTextContentImageContent实现了接口IRowContent

我现在可以添加一些列到列表或真正的“内容”(文本或图像)。

但您也可以添加列和文本/图像。但如果一行包含文本/图像,则不应包含其他项目。

我如何设计我的类结构来支持它?

编辑:一些额外信息: 我想用“流畅的界面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

5 个答案:

答案 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);
        }
    }

答案 1 :(得分:1)

总结并确保我理解正确:

Row类应包含列列表。每列可以是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);
}

答案 2 :(得分:0)

您可以将Row类设为通用:

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

然后,您可以拥有Row<Column>,其中只能包含列,或Row<TextContent>,其中只能包含文字内容。您甚至可以拥有允许混合内容的Row<IRowContent>

如果您想要一个只能包含文字图片内容(但没有列)的行,请添加IRealContent : IRowContent版本,并TextContentImageContent实施IRealContent。然后,Row<IRealContent>只能包含文字和图片。

答案 3 :(得分:0)

向接口本身提供有关问题的详细信息。

public interface IRowContent
{
      bool SupportsChildren { get; }

      // other properties
}

我还会向Row类引入自定义的Add和Remove方法,以确定添加的内容是否可以支持其他内容。

答案 4 :(得分:0)

我可能会做两件事之一。之一:

不是使用Row.Content.Add()添加项目,而是向Row添加方法以添加内容。 Row.AddContent(iRowContent content);并将“逻辑”放在该方法中,以确定是否可以添加任何项目。

或者,不是使用List,而是实现自己的集合IList,并以包含逻辑的方式编写Add()方法。