c# -复杂的变量赋值

本文关键字:变量 赋值 复杂 | 更新日期: 2023-09-27 18:01:59

我有一个类Row。这个类应该有一个content -属性。目前内容类型为:List<IRowContent>

(IRowContent为接口)

其他类ColumnTextContent, ImageContent实现接口IRowContent

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

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

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

Edit:一些额外的信息:我想建立一个布局与"流畅的接口"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

c# -复杂的变量赋值

如果你声明接口

interface IRowContent 
{
    bool SupportsOtherChildren{ get; }
    ...
}
class ImageContent : IRowContent
{
    public bool SupportsOtherChildren
    {
        get { return false; }
    }
}
class Column : IRowContent
{
    public bool SupportsOtherChildren
    {
        get { return true; }
    }
}

你可以重写一个集合的insert和remove方法来支持这个行为:

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

总结一下,确保我理解正确:

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

您可以使您的Row类通用:

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

那么您可以有一个Row<Column>,它只能包含列,或Row<TextContent>,它只能包含文本内容。你甚至可以有一个允许混合内容的Row<IRowContent>

如果您想要一行只能包含文本图像内容(但不包含列),请添加一个接口IRealContent : IRowContent,并让TextContentImageContent实现IRealContent。然后,Row<IRealContent>只能包含文字和图像

将问题的细节抽象到接口本身。

public interface IRowContent
{
      bool SupportsChildren { get; }
      // other properties
}

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

我可能会做两件事中的一件。:

不再使用Row.Content.Add()添加项目,而是在Row中添加一个方法来添加内容。Row.AddContent(iRowContent content);并将您的"逻辑"放入该方法中,以确定是否可以添加任何项目。

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