[英]Difference between using IEnumerator and using an array as an property
我得到了 IEnumerator 的想法,它為 class 提供了迭代能力。我明白了為什么需要 GetEnumerable() 來使用 foreach 語句。 但是我想知道為什么我需要實現 IEnumerator 而我可以將數組聲明為屬性? 我真的很困惑,可以使用一個很好的解釋。 這是我的代碼塊,使用和不使用 IEnumerator 實現的結果是一樣的。
static void Main(string[] args)
{
Customer customer1 = new Customer
{
Name = "Marty",
Surname = "Bird",
Id = 1
};
Customer customer2 = new Customer
{
Name = "Hellen",
Surname = "Pierce",
Id = 2
};
Customers customers = new Customers();
customers.Add(customer1);
customers.Add(customer2);
//Using a property: This one works without an extra GetEnumerator implementation.
foreach (var item in customers.CustomerList)
{
Console.WriteLine(item.Name);
}
//Using with GetEnumerator()
foreach (Customer item in customers)
{
Console.WriteLine(item.Name);
}
}
class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
}
class Customers:IEnumerable
{
private List<Customer> customerList = new List<Customer>();
public List<Customer> CustomerList { get=> customerList; }
public void Add(Customer p)
{
customerList.Add(p);
}
public IEnumerator GetEnumerator()
{
return customerList.GetEnumerator();
}
}
您真的根本不需要實施 IEnumerator。 您可以刪除 Customers class 並替換以下行:
Customers customers = new Customers();
有了這個:
List<Customer> customers = new List<Customers>();
您需要實現 GetEnumerator 的唯一原因是因為您從 IEnumerable 繼承了 class Customers,這是一個聲明該方法的接口。 接口中的所有方法和屬性必須在實現該接口的 class 中實現。
只要給出您顯示的代碼,您就不需要客戶 class,只需使用我上面解釋的列表即可。
但是,如果您確實需要 Customers class,因為您計划向其添加比您展示的更多的功能,一種選擇是從List<Customer>
繼承。 然后它將在 foreach 語句中工作而無需實現 GetEnumerable() 因為 List 已經實現了該方法。
數組屬性通常會導致錯誤。 我們開發了一個可靠的數組屬性,可以避免 foreach 循環中的錯誤。 Microsoft 建議一種不使用 null 值的設計模式,即使沒有數據也是如此。
class Program
{
static void Main()
{
foreach (string item in Empty)
{
System.Console.WriteLine(item); // Never reached
}
}
/// Get an empty array.
public static string[] Empty
{
get
{
return new string[0]; // Won't crash in foreach
}
}
}
NET 的 IEnumerable 接口命名錯誤 - 它應該是 IIterable。 基本上一個 System.Collection.IEnumerable 或(自泛型)System.Collection.Generic.IEnumerable 允許您在 object 上使用 foreach 實現這些接口。另一方面,IEnumerable 基本上說給定一個開始 position 有可能獲得下一個值。 這方面的一個例子可能是無限系列的數字:
public IEnumerable<int> Infinite()
{
int i = 0;
while(true)
yield return i++;
}
如果您想滾動自己的可枚舉Customers
class,這非常簡單:
class Customers : List<Customer>
{
}
而已!
現在你可以這樣做:
Customer customer1 = new Customer
{
Name = "Marty",
Surname = "Bird",
Id = 1
};
Customer customer2 = new Customer
{
Name = "Hellen",
Surname = "Pierce",
Id = 2
};
Customers customers = new Customers();
customers.Add(customer1);
customers.Add(customer2);
foreach (var item in customers)
{
Console.WriteLine(item.Name);
}
話雖如此,您可能想閱讀以下答案: 創建自己的收藏集 class 是一種好習慣嗎? . 在大多數情況下,您可以跳過特殊的 class 並直接使用List<Customer>
。
這是因為數組實現了GetEnumerator()
。 您的 class 可能並不總是將可枚舉的內容存儲在已經為您實現的數據結構中。 您可以變得非常有創意,因為這種模式非常靈活。
以這個class為例:
class Numbers1To5 : IEnumerable<int>
{
public IEnumerator<int> GetEnumerator() => new Numbers1To5Enumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
class Numbers1To5Enumerator : IEnumerator<int>
{
public int Current { get; private set; }
object IEnumerator.Current => Current;
public bool MoveNext()
{
if (Current >= 5)
return false;
Current++;
return true;
}
public void Reset()
{
Current = 0;
}
public void Dispose()
{
}
}
}
如果您有執行以下操作的程序,您會在控制台中顯示數字 1 到 5:
foreach (int number in new Numbers1To5())
Console.WriteLine(number);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.