2013-04-02 32 views
1

我有一个实现MyItems列表的类。 我想要一个方法从该列表中删除一些元素,并且它应该返回删除的项目。 这是我的尝试:?列表<T>和派生类中的GetRange()问题

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

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

不幸的是,GetRange()返回列表,但不MyItemList :( 我该如何处理这更好的方式 铸造不起作用 必须有一个优雅的方式来解决这个非常简单的问题,并保持类型MyItemList内(不脏黑客)。

提前感谢!

+2

您是否考虑过使用组合而不是继承? –

+2

伊利亚是对的;它可能会更好地执行'IList ',然后在内部使用私有'List '作为您的存储。这样,如果将来改变主意,您可以自由决定采用另一种实施策略。问自己一个'MyItemList' *是一种特殊的'List '*,还是它的作用就像是一个MyItems *列表。前者是类继承,后者是接口实现。 –

+0

我同意你两个。另外,如果你只想添加一些额外的List函数,比如'CutOff',那么你可以使用扩展方法并且坚持使用泛型类型,即'List ' – sambomartin

回答

3

这应该做的伎俩,但我强烈建议对组成,在这里你将存储重新设计内部列出

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

+0

感谢您的快速回答!如果我理解你的权利,你建议做这样的事情: public class MyItemList { List _list;我的项目清单结果=新的MyItemList(_list.GetRange(0,count));我的项目清单结果=新MyItemList(_list.GetRange(0,count)); _list.RemoveRange(0,count); 返回结果; } 该解决方案的优点是什么?为什么它更好? 我拿继承获得ListT的所有方法的更多特定版本的ListT ... – CSharper

+0

@CSharper查看我的回答的更新和笔记 –

2

访问MyItem定义的方法你可以只是一个List<MyItem>MyItem[]与删除项目恢复需要。 或使用列表<>构造函数,它带有一个可枚举的。

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

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; 
    } 
} 
+0

几乎与llya的相同!有快速和死亡。 – sambomartin

1

不要List<MyItem>继承(除非你试图做的是避免打字尖括号都相反,封装一个List<MyItem>作为。你的类的后备存储,并只公开你的问题域所需的特定/方法和属性。通过继承List<MyObject>,你正在泄漏实现细节并将你自己绑定到特定类型的后备存储。你想保持最小的公共表面面积这样做有助于测试,并使未来的变化更容易呃。

如果您想要与标准SCG集合类型的互操作性,最好显式地只实现您需要的接口—。