IEnumerable<T>,IEnumerable,IEnumerator<T>,IEnumerator

本文详细解析了IEnumerable与IEnumerator接口的区别及其应用场景。IEnumerable定义了一个可被枚举的对象,而IEnumerator则用于实际执行枚举操作。通过示例代码展示了如何在同一个对象上进行多次枚举。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接口定义说明:

namespace System.Collections.Generic
{
    // 摘要:
    //     公开枚举器,该枚举器支持在指定类型的集合上进行简单迭代。
    //
    // 类型参数:
    //   T:
    //     要枚举的对象的类型。
    [TypeDependency("System.SZArrayHelper")]
    public interface IEnumerable<out T> : IEnumerable
    {
        // 摘要:
        //     返回一个循环访问集合的枚举器。
        //
        // 返回结果:
        //     可用于循环访问集合的 System.Collections.Generic.IEnumerator<T>。
        IEnumerator<T> GetEnumerator();
    }
}

 

namespace System.Collections
{
    // 摘要:
    //     公开枚举器,该枚举器支持在非泛型集合上进行简单迭代。
    [ComVisible(true)]
    [Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
    public interface IEnumerable
    {
        // 摘要:
        //     返回一个循环访问集合的枚举器。
        //
        // 返回结果:
        //     可用于循环访问集合的 System.Collections.IEnumerator 对象。
        [DispId(-4)]
        IEnumerator GetEnumerator();
    }
}

namespace System.Collections.Generic
{
    // 摘要:
    //     支持在泛型集合上进行简单迭代。
    //
    // 类型参数:
    //   T:
    //     要枚举的对象的类型。
    public interface IEnumerator<out T> : IDisposable, IEnumerator
    {
        // 摘要:
        //     获取集合中位于枚举数当前位置的元素。
        //
        // 返回结果:
        //     集合中位于枚举数当前位置的元素。
        T Current { get; }
    }
}

namespace System.Collections
{
    // 摘要:
    //     支持对非泛型集合的简单迭代。
    [ComVisible(true)]
    [Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
    public interface IEnumerator
    {
        // 摘要:
        //     获取集合中的当前元素。
        //
        // 返回结果:
        //     集合中的当前元素。
        //
        // 异常:
        //   System.InvalidOperationException:
        //     枚举数定位在该集合的第一个元素之前或最后一个元素之后。
        object Current { get; }

        // 摘要:
        //     将枚举数推进到集合的下一个元素。
        //
        // 返回结果:
        //     如果枚举数成功地推进到下一个元素,则为 true;如果枚举数越过集合的结尾,则为 false。
        //
        // 异常:
        //   System.InvalidOperationException:
        //     在创建了枚举数后集合被修改了。
        bool MoveNext();
        //
        // 摘要:
        //     将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。
        //
        // 异常:
        //   System.InvalidOperationException:
        //     在创建了枚举数后集合被修改了。
        void Reset();
    }
}

 

Can anyone please explain to me what is the difference between IEnumerable & IEnumerator , and how to use them?

http://stackoverflow.com/questions/2635818/ienumerable-ienumerator

 

Generally, an IEnumerable is an object which can be enumerated, such as a list or array. An IEnumerator is an object that stores the state of the enumeration.

The reason they're not one and the same is that you could have multiple enumerations over the same object at the same time - even in a single-threaded application. For example, consider the following code:

foreach (x in mylist)
{
    foreach (y in mylist)
    {
        if (x.Value == y.Value && x != y)
        {
            // Found a duplicate value
        }
    }
}

This would work fine if mylist is a proper implementation of IEnumerable, but it would fail if mylist returned itself as the enumerator.

=======================================================================================================================

The IEnumerable interface defines a class which can be enumerated over, i.e. it contains elements which can be accessed through enumeration.

The IEnumerator interfaces defines a class which can perform enumeration over a sequence of elements.

The distinction is that IEnumerable means "you can enumerate me", where IEnumerator performs the task of enumeration.

To elaborate a little more, IEnumerable exposes a method GetEnumerator. This method returns an IEnumerator you can then use to perform the enumerating. Normally you don't deal with this method yourself, because the foreach keyword handles it for you.

foreach(int element in myList)
{
    // Do some work...
}

This code is actually expanded for you by the compiler into this:

IEnumerator enumerator = myList.GetEnumerator();
try 
{
   while (enumerator.MoveNext()) 
   {
      int element = (int)enumerator.Current;
      // Do some work...
   }
}
finally 
{
   IDisposable disposable = enumerator as System.IDisposable;
   if (disposable != null) disposable.Dispose();
}

As you can see, an IEnumerator is used here to perform the enumeration through the elements.

 

(1)、IEnumerable<T>,IEnumerable:两者的区别就是前者是泛型的,当然他就具有泛型的优点,即类型安全(其实为什么叫泛型,一点都不泛泛呀?类型直接指定难道不比object具体多了吗?哎!!!),IEnumerator<T>,IEnumerator的关系类似。

(2)、IEnumerable和IEnumerator:两者的区别参考上面的查询资料可以简单概括为:IEnumerable表示是可枚举的,也就是说一个对象的类型如果是IEnumerable的话,那么就表示我们可以用foreach这种语法进行循环,也可以在LINQ查询中使用。那么什么是IEnumerator?它表示的是一个枚举器的接口定义,也就是说如果一个类实现了IEnumerator的话,我们就是调用Current,MoveNext(),Reset()这些方法对这个类进行遍历,当然也可以用foreach循环。观察最开始我们写出来的接口定义,我们可以看到IEnumerable中的实现其实返回的是一个IEnumerator对象,也就是说IEnmerable的底层其实是IEnumerator。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值