【问题标题】:Alter elements of generic collection property in a subclass child collection更改子类子集合中通用集合属性的元素
【发布时间】:2013-02-14 14:23:38
【问题描述】:

我有一个简单的接口 ElementContainer(它也是一个元素),其中包含一个包含 Elements 的列表:

interface IElementContainer : IElement 
{
    List<Element> Elements { get; }
}

现在我有一个实现这个接口的类:

class ConcreteContainer : IElementContainer
{
    List<IElement> Elements { get; private set; }
}

但我不希望该类成为所有元素的容器,而仅适用于其中的一个子集,比如 SpecificElement,但是这是不可能的(当然):

class SpecificElementContainer : IElementContainer
{
    List<SpecificElement> Elements { get; private set; }
}

因此我想到了类似的东西:

class SpecificElementContainer : IElementContainer
{
    List<IElement> Elements { get; private set; }
    List<SpecificElement> SpecificElements
    {
       get 
       {
          return return Elements.FindAll(el => el is T).Select<IElement, T>(el => (T)el).ToList<T>();
       }
 }

但是这样我不能做类似的事情:SpecificContainer.SpecificElements.Add(...) 因为它没有添加到元素中。除此之外......这样做闻起来很腥。

任何线索如何以理智的方式重组它?

在 Jon Skeet 的回答后编辑

阅读 Jons 的评论,我的问题实际上比我上面显示的要复杂一些,但我忘记了一些非常重要的信息。

当我有一个实现上述接口的类并且元素列表填充如下:

Elements = { ConcreteElementA, ConcreteElementA, ConcreteElementC, ConcreteElementB }

我想要的是我可以这样做ConcreteContainer.ConcreteElementCs.Add(new ConcreteElementC()),这将导致:

Elements = { ConcreteElementA, ConcreteElementA, ConcreteElementC, ConcreteElementB, ConcreteElementC }

其他编辑

经过一番困惑后,我想将我的问题重新表述如下: 我有一个集合List&lt;Element&gt; OriginalCollection。我想创建一个包含实现 Element、ConcreteElement、List&lt;ConcreteElement&gt; Subset 的元素的子集集合,并以OriginalCollection 也被修改的方式添加到其中。

【问题讨论】:

  • 建议 - 使用与 .NET 中所有地方相同的代码约定,即以前缀 I: IElement 命名的接口
  • 谢谢,我会记住的;我上面的帖子仅用于说明目的。
  • @avanwieringen:是的,但是当你试图说明某些事情时,清楚仍然很重要......
  • 你说得对,我已经改了。

标签: c# generics inheritance collections


【解决方案1】:

听起来你的ElementContainer 接口应该是通用的:

interface ElementContainer<T> : Element where T : Element
{
    List<T> Elements { get; }
}

然后:

class SpecificElementContainer : ElementContainer<SpecificElement>
{
    List<SpecificElement> Elements { get; private set; }
}

【讨论】:

  • 感谢您的回答。我用一个更复杂的问题更新了我的问题,这实际上是我的意思,但未能正确说明:)
  • @avanwieringen:恐怕你还没有清楚地说明它 - 我不明白你的更新。如果 ConcreteElementCs 始终只是一个副本,那么您根本无法添加到它(并期望发生任何有用的事情) - 您需要添加到 Elements 来代替。你为什么不这样做呢?
  • 很抱歉给您带来了困惑,感谢您的帮助。有什么方法可以检索集合的子集,以修改原始集合的方式添加到该集合中?恐怕这是不可能的,我将不得不使用您提供的解决方案重构我的代码,这实际上比我想创建的东西要理智得多。
  • @avanwieringen:我认为你必须编写自己的集合来支持这一点。这是可行的,但在各个方面都很困难。
  • 是的,我害怕那个。谢谢!我会重新思考我的架构。
猜你喜欢
  • 2016-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多