2013-04-02 47 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集合類型的互操作性,最好顯式地只實現您需要的接口—。