簡體   English   中英

使用 IEnumerator 和使用數組作為屬性的區別

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM