如何创建包含抽象元素列表的集合类

时间:2012-03-21 17:46:38

标签: c# list collections derived-class

我需要创建一个包含抽象片段列表的集合。

我有一些来自分段的派生类,即LineSegment : Segment

public class Path : IEnumerable
{
        private List<Segment> segments = new List<Segment>();


        public List<Segment> Segments 
        {  
            set { Segments = value;}
            get { return this.segments; } 
        }
        //some code inc ctrs

}

我希望能够将LinePath定义为基类Path的派生类

public class LinePath : Path, IEnumerable
{        
        public LinePath(List<LineSegment> s)
        {
            this.Segments = s; //error
        }
}

但是我一直在遇到无法轻松编辑LinePath的内容的情况,因为它包含的列表仍然是Segment列表(大量的投射)或者当我希望从Path以及其他派生的细分中创建正常的LinePath

这类问题的标准格式是什么?也许我应该放弃LinePath并只使用Path个对象?

我意识到这个问题可能有些含糊不清,我为此道歉,但需要弄清楚究竟是什么导致我混淆并避免混乱的解决方案。

3 个答案:

答案 0 :(得分:0)

我不知道我是否理解这个问题,但我认为这是你想要的行为。

public class GenericPath<T> : IEnumerable
    {
        private List<T> items = new List<T>();


        public List<T> Items
        {
            set { this.items = value; }
            get { return this.items; }
        }
        //some code inc ctrs

    }

    public class Segment
    {
    }

    public class Path : GenericPath<Segment>
    {        

    }

    public class LinePath : GenericPath<Path>
    {
    }

答案 1 :(得分:0)

我看到了几个选项。首先,寻找机会将您的列表用作IEnumerable<T>而不是List<T>,因为List<LineSegment> 可以仅用于投放IEnumerable<Segment>列表,没有强制转换所有元素(假设C#4.0或更高版本)。

其次,考虑使路径派生自Segment(PathSegment,如果愿意),因此您可以将Path中的LinePath包含为单个对象,而不是将其所有LineSegment元素添加到Path的列表中细分元素。

您可能希望在codereview.stackexchange.com上发布更大的代码摘录。

答案 2 :(得分:0)

我认为最好定义泛型参数T应该是Segment类型。避免使用Path<string>

之类的内容

此外,您不需要从IEnumerable继承LinePath - 它将从Path继承此接口实现。并考虑使用IEnumerable接口的通用版本。

  public class Path<T> : IEnumerable<T>
        where T : Segment // here we define that parameter is Segment or its child
    {
        private List<T> _segments = new List<T>();        

        public List<T> Segments
        {
            set { _segments = value; }
            get { return _segments; }
        }

        public IEnumerator GetEnumerator()
        {
            throw new NotImplementedException();
        }
    }

    public class LinePath<T> : Path<T> 
        where T : LineSegment // parameter is LineSegment or its child
    {

        public LinePath(List<T> segments)
        {
            // no error because Path.Segments of type List<LineSegment>
            Segments = segments;
        }
    }