在派生类</t>中列出<t>和GetRange()问题

时间:2013-04-02 23:16:35

标签: c# list

我有一个实现MyItems列表的类。 我想要从该列表中切割一些元素的方法,它应该返回已删除的项目。 这就是我试过的:

public class MyItemList : List<MyItem>
{
    ...

    public MyItemList cutOff(int count)
    {
        MyItemList result = this.GetRange(0, count);
        this.RemoveRange(0, count);
        return result;
    }

不幸的是,GetRange()返回List而不是MyItemList :( 我怎样才能更好地处理这个问题? 铸造不起作用。 必须有一种优雅的方法来解决这个非常简单的问题,并保持在MyItemList类型内(没有肮脏的黑客攻击)。

提前致谢!

3 个答案:

答案 0 :(得分:3)

这应该可以解决问题,但我强烈建议重新设计组合,你将在内部存储List

public class MyItemList : List<MyItem>
{
    public MyItemList(){}

    public MyItemList(IEnumerable<MyItem> sequence): base(sequence) {}

    public MyItemList cutOff(int count)
    {
        MyItemList result = new MyItemList(this.GetRange(0, count));
        this.RemoveRange(0, count);
        return result;
    }
}

还可以考虑创建列表的开放通用类型,例如MyList<T> : List<T>MyList<T> : List<T> where T : MyItem,以便该类的客户端可以利用泛型

编辑:好的,我已经为List<T>实现了通用版本作为扩展方法,这将帮助您在MyItemList类之外的列表中使用更多逻辑

public static class ListExtensions
{
    public static List<T> CutOff<T>(this List<T> list, int count)
    {
        var result = list.GetRange(0, count);
        list.RemoveRange(0, count);
        return result;
    }
}

现在你可以

var list = new List<int> {1,2,3,4,5,6};

Console.WriteLine ("cutted items:");
Console.WriteLine (string.Join(Environment.NewLine, list.CutOff(2)));

Console.WriteLine ("items in list:");
Console.WriteLine (string.Join(Environment.NewLine, list));

打印:

cutted items:
1
2
items in list:
3
4
5
6

另一个注意事项:

我建议这样做

public class MyItemList<T> : IList<T> where T : MyItem
{
     private List<T> list;

     //here will be implementation of all methods required by IList
     //that will simply delegate to list field

}

请注意,如果MyItemList中的所有逻辑都是通用的(可以应用于List<T>,如Cutoff方法),则可能不需要单独的类。 where T : MyItem也是可选的,只有在MyItemList

中访问MyItem中定义的方法时才需要

答案 1 :(得分:2)

您只需返回已删除邮件的List<MyItem>MyItem[]即可。 或使用列表&lt;&gt;采用不可数的构造函数。

没有编译这个 - 但应该没问题

public class MyItemList : List<MyItem>
{
   // def ctor
   public MyItemList() {}

   public MyItemList(IEnumerable<MyItems> items): base(items) {}

   public MyItemList cutOff(int count)
    {
        MyItemList result = new MyItemList(this.GetRange(0, count));
        this.RemoveRange(0, count);
        return result;
    }
}

答案 2 :(得分:1)

不要继承List<MyItem>(除非你要做的就是避免输入尖括号。而是将封装一个List<MyItem>作为你的班级支持商店并且只公开问题域所需的特定/方法和属性。通过继承List<MyObject>,您正在泄漏实现细节并将自己绑定到特定类型的后备存储。您希望保持所需的最小公共表面区域完成工作。这样做有助于测试,并使未来的变化更容易。

如果您希望互操作性与标准SCG集合类型,请仅实现您需要的接口 - 最好是明确的。