2010-08-24 60 views
4

我寫了一個CustomerCollection類,它實現了IEnumerable和IEnumerator接口。現在我希望CustomerCollection類對象可以通過Where()和Find()函數進行搜索,並且還希望從CustomerCollection類中獲取類型爲Customer的List對象。請幫忙。另外,接口的實現是正確的。IEnumerable集合到列表

public class Customer 
{ 
    private int _CustomerID; 
    private string _CustomerName; 

    public Customer(int customerID) 
    { 
     this._CustomerID = customerID; 
    } 

    public int CustomerID 
    { 
     get 
     { 
      return _CustomerID; 
     } 
     set 
     { 
      _CustomerID = value; 
     } 
    } 

    public string CustomerName 
    { 
     get 
     { 
      return _CustomerName; 
     } 
     set 
     { 
      _CustomerName = value; 
     } 
    } 
} 

public class CustomerController 
{ 
    public ArrayList PopulateCustomer() 
    { 
     ArrayList Temp = new ArrayList(); 

     Customer _Customer1 = new Customer(1); 
     Customer _Customer2 = new Customer(2); 

     _Customer1.CustomerName = "Soham Dasgupta"; 
     _Customer2.CustomerName = "Bappa Sarkar"; 

     Temp.Add(_Customer1); 
     Temp.Add(_Customer2); 

     return Temp; 
    } 
} 

public class CustomerCollection : IEnumerable, IEnumerator 
{ 
    ArrayList Customers = null; 
    IEnumerator CustomerEnum = null; 

    public CustomerCollection() 
    { 
     this.Customers = new CustomerController().PopulateCustomer(); 
     this.CustomerEnum = Customers.GetEnumerator(); 
    } 

    public void SortByName() 
    { 
     this.Reset(); 
    } 

    public void SortByID() 
    { 
     this.Reset(); 
    } 

    public IEnumerator GetEnumerator() 
    { 
     return (IEnumerator)this; 
    } 

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

    public void Reset() 
    { 
     CustomerEnum.Reset(); 
    } 

    public bool MoveNext() 
    { 
     return CustomerEnum.MoveNext(); 
    } 

    public object Current 
    { 
     get 
     { 
      return (Customer)CustomerEnum.Current; 
     } 
    } 

} 
+1

你的集合類不應該實現IEnumerable **和**的IEnumerator(除了極少數情況下,只有永遠的零元素)。統計員是有狀態的,枚舉數不是。 GetEnumerator()被多次調用時,您的代碼將無法工作。 – 2010-08-24 14:08:52

+0

你是指'IEnumerable '/'列表'或者確切地說'IEnumerable' /'List'? – abatishchev 2010-08-24 14:14:10

+3

爲什麼不只是使用列表,你可以免費獲得所有的Where和Linq函數...... – chugh97 2010-08-24 14:34:50

回答

1

這將做你想做的。請注意,我抽象出IEnumerable使其可重用,並降低了所有其他類的複雜性。

//Write your Test first 
public class Test 
{ 
    public void TestEnumerator() 
    { 
     var customers = new CustomerCollection(); 
     var qry = 
      from c in customers 
      select c; 

     foreach (var c in qry) 
     { 
      Console.WriteLine(c.CustomerName); 
     } 

     //Create a new list from the collection: 
     var customerList = new List<Customer>(customers); 
    } 
} 

public abstract class MyColl<T> : IEnumerable<T> 
{ 
    protected T[] Items; 
    public IEnumerator<T> GetEnumerator() 
    { 
     foreach (T item in Items) 
     { 
      yield return item; 
     } 
    } 
    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

public class Customer 
{ 
    public Customer(int customerID) 
    { 
     CustomerID = customerID; 
    } 
    public int CustomerID { get; set; } 
    public string CustomerName { get; set; } 
} 

public class CustomerController 
{ 
    public Customer[] PopulateCustomer() { 
     return new [] {new Customer(1) {CustomerName = "Soham Dasgupta"}, 
         new Customer(2) {CustomerName = "Bappa Sarkar"}}; 
    } 
} 

public class CustomerCollection : MyColl<Customer> 
{ 

    public CustomerCollection() 
    { 
     Items = new CustomerController().PopulateCustomer(); 
    } 
} 
4

您可以在自己的IEnumerable致電Cast<Customer>(),這將給你一個IEnumerable<Customer>,或只是實施IEnumerable<Customer>開始。 LINQ幾乎完全吸引到IEnumerable<T>,而不是IEnumerable。一旦你這樣做了,你會得到所有的LINQ免費對象善良。

+1

你可能不應該緩存你的枚舉器,而是每次調用'GetEnumerator'時返回一個新的,每次調用' GetEnumerator'應該返回一個枚舉集合的對象,而不需要使用其他任何東西。有兩個枚舉共享相同的枚舉器是有問題的。 – 2010-08-24 14:10:00

2

我建議使用OfType<T>()代替Cast<T>()因爲如果你的集合包含T1和T2,collection.Cast<T1>()將拋出一個錯誤,而collection.OfType<T1>()將返回IEnumerable<T1>包含T1不是T2

+0

啊,但是當那裏有一個意想不到的元素時拋出一個異常是不是一件壞事? – 2010-08-24 14:12:52

+0

@Kirk:當然,視情況而定。我使用'OfType'的時間99.99%將所有這些.NET 2.0內置的非泛型集合(如ControlCollection,ElementCollection等等)轉換爲IEnumerable,所以我不確定它們確切地包含了什麼一個額外的支票是好的 – abatishchev 2010-08-24 14:16:43

+2

好吧,他的班級的名字叫做「CustomerCollection」,所以如果它包含任何其他東西,它看起來會令人吃驚(並且值得一個例外)。 :) – 2010-08-24 14:30:32

1
public class CustomerController 
{ 
    public List<Customer> PopulateCustomer() 
    { 
     List<Customer> Temp = new ArrayList(); 

     Customer _Customer1 = new Customer(1); 
     Customer _Customer2 = new Customer(2); 

     _Customer1.CustomerName = "Soham Dasgupta"; 
     _Customer2.CustomerName = "Bappa Sarkar"; 

     Temp.Add(_Customer1); 
     Temp.Add(_Customer2); 

     return Temp; 
    } 
} 


public class CustomerCollection : List<Customer> 
{ 
    List<Customer> Customers = new List<Customer>(); 


    public CustomerCollection() 
    { 
     this.Customers = new CustomerController().PopulateCustomer(); 
    }  

} 
1
new List<Customer>(myCustomerEnumerator); 
1
的唯一實例

用於創建您自己的收集實現的推薦基類是System.Collections.ObjectModel.Collection<T>

(來自MSDN)
提供此基類以便實施者創建自定義集合。鼓勵實施者擴展這個基類,而不是創建他們自己的基類。

public class CustomerCollection : Collection<Customer> 
{ 
} 
相關問題