2014-01-20 92 views
2

當一個類必須有某種對象的容器(集合)時,有幾種選擇,我想知道我更喜歡什麼實現。在課堂上有一個集合

下面就跟隨我找到的選項:

public class AClass : IEnumerable<string>{ 
    private List<string> values = new List<string>() 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public IEnumerator<T> GetEnumerator(){ 
     return values.GetEnumerator(); 
    } 
} 

優點:ACLASS不依賴於具體實現的集合(在這種情況下列表)。

缺點:ACLASS沒有接口,用於添加和刪除元素

public class AClass : ICollection<string>{ 
    private List<string> values = new List<string>() 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public IEnumerator<T> GetEnumerator(){ 
     return values.GetEnumerator(); 
    } 

    //other ICollectionMembers 
} 

優點:同爲IEnumerable加上它具有界面添加和刪除元素

缺點: ICollection接口定義了其他很少使用的方法,並且爲了實現接口而實現這些方法會很枯燥。此外,IEnumerable LINQ擴展會照顧其中的一些。

public class AClass : List<string>{ 

} 

優點:無需實施任何方法。主叫方可以調用任何由列表執行的方法

缺點:AClass依賴於集合列表,如果它改變了一些調用者代碼可能需要改變。另外AClass不能繼承任何其他類。

現在的問題是:我更喜歡哪一個表明我的類包含一個支持Add和Remove操作的集合?或其他建議...

回答

3

我的建議是隻定義泛型列表類的內部和編寫額外的AddRemove方法,像這樣和實現IEnumerable:

public class MyClass : IEnumerable 
{ 
    private List<string> myList; 

    public MyClass() 
    { 
     myList = new List<string>(); 
    } 

    public void Add(string item) 
    { 
     if (item != null) myList.Add(item); 
    } 

    public void Remove(string item) 
    { 
     if (myList.IndexOf(item) > 0) myList.Remove(item); 
    } 

    public IEnumerable<string> MyList { get { return myList; } } 

    public IEnumerator GetEnumerator() 
    { 
     return myList.GetEnumerator(); 
    } 
} 

這是最好的方式,如果你不不想實現自己的collection.You不需要實現一個接口到AddRemove方法。像這樣的其他方法,我想你是否符合你的需求。

+0

由於您已擁有Property來獲取列表,因此不需要添加和刪除方法。我喜歡ideia,但我會讓它返回ICollection,所以它不會和我的第三個選項一樣。 –

+0

你說得對,你可以把它改成ICollection,或者IEnumerable更好。如果你返回IEnumerable,用戶不能直接向列表添加項目。 –

1

嗯,這實際上是一個基於意見的問題,它不是專門用於SO的。但是,所有的實現都有不同的pro和con,就像你列出的那樣,你實現的是一個最適合應用程序使用的選項。

在我的個人觀點我會選擇一個並添加您需要與您的內部集合接口的方法。這很容易實現並且使用簡單。

有點像。

public class AClass : IEnumerable<string> 
{ 
    public AClass() 
    { 
     this.values = new List<string>(); 
    } 

    private readonly List<string> values; 

    public void Add(string inputString) 
    { 
     this.values.Add(inputString); 
    } 

    public void Remove(string inputString) 
    { 
     this.values.Remove(inputString); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public IEnumerator<string> GetEnumerator() 
    { 
     return values.GetEnumerator(); 
    } 
} 

現在,這有簡單的添加\刪除功能。另請注意,我使用了一個readonly列表,因爲列表在構造函數被調用後不需要休息。

更新AS根據評論發表評論。

是的,你確實已經從列表轉換爲AClass其他類(你將不得不反正)。我已經在構造函數中添加了一個額外的構造函數和一個隱式操作符來從List或IEnumerable進行強制轉換。

public class AClass : IEnumerable<string> 
{ 
    public static implicit operator AClass(List<string> collection) 
    { 
     return new AClass(collection); 
    } 

    public static implicit operator List<string>(AClass aClass) 
    { 
     return aClass.values; 
    } 

    public AClass() 
    { 
     this.values = new List<string>(); 
    } 

    public AClass(IEnumerable<string> collection) 
    { 
     this.values = collection.ToList(); 
    } 

    private readonly List<string> values; 

    public void Add(string inputString) 
    { 
     this.values.Add(inputString); 
    } 

    public void Remove(string inputString) 
    { 
     this.values.Remove(inputString); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public IEnumerator<string> GetEnumerator() 
    { 
     return values.GetEnumerator(); 
    } 
} 

這可能被用來作爲下列方式:

List<string> listA = new List<string>(); 

AClass classA = new AClass(); //parameterless constructor 
AClass classA1 = new AClass(listA); //simple constructor call with collection 
AClass classA2 = (AClass)listA; //direct cast 
List<string> listB = (List<string>)listA; //cast back to a list 

只是一個想法,再次還是一個個人觀點

+0

這樣做的缺點是,你將不得不投票給AClass添加和刪除(如果你只知道它是一個IEnumerable) –

+0

我已經更新了基於評論的回覆 – Nico

+0

我真的不喜歡鑄造操作符的Ideia (可能是個人品味),但是有一個很好的構造函數調用。 –

0

這是什麼塞爾曼提出這樣他的回答符合我的預期只是一個小的調整:

public class MyClass : IEnumerable<string> 
{ 
    private List<string> myList; 

    public MyClass() 
    { 
     myList = new List<string>(); 
    } 

    public ICollection<string> MyList { get { return myList; } } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public IEnumerator<T> GetEnumerator(){ 
     return myList.GetEnumerator(); 
    } 
} 
0

我喜歡你解釋你的想法的方式。

您已經找到3種解決某些問題的完美商品方法。你的利弊讓我覺得你正確地理解了他們。

沒有銀彈來解決所有問題。但你最好有一個軟件架構師工具箱包裝設計模式和一個常識。

下一次當你面臨挑戰時,請使用最好的工具來完成這項工作!

+0

在完成計算機工程專業的大學學位後,我懷疑這個問題是相當糟糕的。但是,嘿,所有的問題都應該提出來,我也在尋求一致性,因爲無論什麼時候出現這個問題,我都會以不同的方式面對它。現在我可以擁有一致性和我喜歡的方式,並且感覺合理的實現它。 –

+0

它根本不是蝙蝠,完全相反。當我想在其構造函數中填充一些已知數據時,我通常使用通用List或繼承它。但並不總是這樣。 –