×

Khác biệt giữa IEnumerable và IEnumerator trong C#

Trong C#, cả IEnumerableIEnumerator đều là các giao diện được sử dụng để lặp qua một tập hợp các đối tượng. Tuy nhiên, chúng có các mục đích và cách sử dụng khác nhau. Dưới đây là sự khác biệt chính giữa chúng:

1. IEnumerable

  • Mục đích: IEnumerable là một giao diện cung cấp một enumerator để lặp qua một tập hợp.
  • Phương thức: Nó chỉ có một phương thức duy nhất là GetEnumerator().
  • Trả về: Phương thức GetEnumerator() trả về một đối tượng IEnumerator.
  • Đặc điểm: IEnumerable không quản lý trạng thái của quá trình lặp, mà chỉ cung cấp một enumerator.
public interface IEnumerable
{
    IEnumerator GetEnumerator();
}
  • Ví dụ sử dụng:
public class MyCollection : IEnumerable
{
    private string[] _items = { "item1", "item2", "item3" };

    public IEnumerator GetEnumerator()
    {
        return new MyEnumerator(_items);
    }
}

2. IEnumerator

  • Mục đích: IEnumerator là một giao diện cho phép lặp qua một tập hợp.
  • Phương thức và Thuộc tính:
    • MoveNext(): Di chuyển tới phần tử kế tiếp trong tập hợp.
    • Reset(): Đặt lại enumerator về vị trí ban đầu (trước phần tử đầu tiên trong tập hợp).
    • Current: Lấy phần tử hiện tại trong tập hợp.
  • Đặc điểm: IEnumerator quản lý trạng thái của quá trình lặp, bao gồm vị trí hiện tại của enumerator trong tập hợp.
public interface IEnumerator
{
    bool MoveNext();
    void Reset();
    object Current { get; }
}
  • Ví dụ sử dụng:
public class MyEnumerator : IEnumerator
{
    private string[] _items;
    private int _position = -1;

    public MyEnumerator(string[] items)
    {
        _items = items;
    }

    public bool MoveNext()
    {
        _position++;
        return (_position < _items.Length);
    }

    public void Reset()
    {
        _position = -1;
    }

    public object Current
    {
        get
        {
            try
            {
                return _items[_position];
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }
}

3. Tổng kết sự khác biệt

  • IEnumerable:

    • Cung cấp một phương thức GetEnumerator() để trả về một enumerator.
    • Thường được sử dụng cho các tập hợp (collections) để cung cấp khả năng lặp qua các phần tử của chúng.
    • Không quản lý trạng thái của quá trình lặp.
  • IEnumerator:

    • Cung cấp các phương thức MoveNext(), Reset(), và thuộc tính Current để lặp qua một tập hợp.
    • Được trả về bởi GetEnumerator() của IEnumerable.
    • Quản lý trạng thái của quá trình lặp.

Ví dụ tổng hợp

Dưới đây là ví dụ tổng hợp về cách sử dụng cả IEnumerableIEnumerator:

using System;
using System.Collections;

public class MyCollection : IEnumerable
{
    private string[] _items = { "item1", "item2", "item3" };

    public IEnumerator GetEnumerator()
    {
        return new MyEnumerator(_items);
    }
}

public class MyEnumerator : IEnumerator
{
    private string[] _items;
    private int _position = -1;

    public MyEnumerator(string[] items)
    {
        _items = items;
    }

    public bool MoveNext()
    {
        _position++;
        return (_position < _items.Length);
    }

    public void Reset()
    {
        _position = -1;
    }

    public object Current
    {
        get
        {
            try
            {
                return _items[_position];
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }
}

public class Program
{
    public static void Main()
    {
        MyCollection collection = new MyCollection();
        foreach (var item in collection)
        {
            Console.WriteLine(item);
        }
    }
}

Tổng kết

IEnumerableIEnumerator là hai giao diện quan trọng trong C# giúp bạn lặp qua các tập hợp. IEnumerable cung cấp một enumerator, trong khi IEnumerator quản lý quá trình lặp qua từng phần tử. Hiểu rõ sự khác biệt giữa chúng giúp bạn xây dựng các tập hợp tùy chỉnh và làm việc với các tập hợp một cách hiệu quả.

Comments