C# ienumerable vs list<;T>;

C# ienumerable vs list<;T>;,c#,.net,ienumerable,C#,.net,Ienumerable,据说IEnumerable用于自定义集合。其中一个用途是用于遍历自定义集合的foreach循环 然而,我的问题是,与其创建一个首先实现IEnumerable的自定义集合,然后构造另一个类来实现IEnumerator来存储一组自定义对象,为什么我们不能只使用list 提前感谢您的帮助。当然您可以使用列表 如果List符合您的需要,那么使用它,不要创建继承自IEnumerable的新类。当然,您可以使用List 如果List符合您的需要,请使用它,不要创建继承自IEnumerable的新类。您可以使

据说IEnumerable用于自定义集合。其中一个用途是用于遍历自定义集合的foreach循环

然而,我的问题是,与其创建一个首先实现
IEnumerable
的自定义集合,然后构造另一个类来实现
IEnumerator
来存储一组自定义对象,为什么我们不能只使用
list


提前感谢您的帮助。

当然您可以使用
列表


如果
List
符合您的需要,那么使用它,不要创建继承自
IEnumerable
的新类。当然,您可以使用
List


如果
List
符合您的需要,请使用它,不要创建继承自
IEnumerable
的新类。您可以使用
List
或任何其他通用集合类型。毕竟
List
实现了
IEnumerable


您是否有需要使用定制集合覆盖的特定边缘案例?

您可以使用
列表
或任何其他通用集合类型。毕竟
List
实现了
IEnumerable


您是否有需要使用定制集合来覆盖的特定边缘案例?

当然,您可以将您的成员定义为
列表
,但这会将类的客户绑定到特定的实现。如果将成员定义为
IEnumerable
(假设使用者只想枚举您的集合),则可以将实现更改为实现接口的不同集合类型,而不会破坏约定。如果您将其从
List
更改为
SortedSet
,以实现订单,您的消费者不会受到影响

这基本上是针对接口而不是具体类型进行编码的优势


如果您的消费者想要的不仅仅是枚举,那么您可以使用不同的接口,即。
ICollection

当然,您可以将您的成员定义为
列表
,但是它将类的客户绑定到特定的实现。如果将成员定义为
IEnumerable
(假设使用者只想枚举您的集合),则可以将实现更改为实现接口的不同集合类型,而不会破坏约定。如果您将其从
List
更改为
SortedSet
,以实现订单,您的消费者不会受到影响

这基本上是针对接口而不是具体类型进行编码的优势


如果您的消费者想要的不仅仅是枚举,那么您可以使用不同的接口,即。
ICollection

因为您可能希望实现不同的数据结构
IEnumerable
抽象了序列的概念,而
List
具有索引、添加/删除项及其自身的数据结构的概念

作为不同结构的一个示例,这里有一个类,它允许您输入无限的
foreach
循环

public class InfiniteSequence : IEnumerable<int>
{
    public IEnumerator<int> GetEnumerator()
    {
        return new InfiniteEnumerator();
    }

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

    class InfiniteEnumerator : IEnumerator<int>
    {
        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public bool MoveNext()
        {
            Current++;
            return true;
        }

        public void Reset()
        {
            Current = 0;
        }

        public int Current { get; private set; }

        object IEnumerator.Current
        {
            get { return Current; }
        }
    }
}
公共类无穷序列:IEnumerable
{
公共IEnumerator GetEnumerator()
{
返回新的InfiniteNumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
返回GetEnumerator();
}
类无穷枚举器:IEnumerator
{
公共空间处置()
{
抛出新的NotImplementedException();
}
公共图书馆
{
电流++;
返回true;
}
公共无效重置()
{
电流=0;
}
public int Current{get;private set;}
对象IEnumerator.Current
{
获取{返回当前;}
}
}
}

因为您可能希望实现不同的数据结构
IEnumerable
抽象了序列的概念,而
List
具有索引、添加/删除项及其自身的数据结构的概念

作为不同结构的一个示例,这里有一个类,它允许您输入无限的
foreach
循环

public class InfiniteSequence : IEnumerable<int>
{
    public IEnumerator<int> GetEnumerator()
    {
        return new InfiniteEnumerator();
    }

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

    class InfiniteEnumerator : IEnumerator<int>
    {
        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public bool MoveNext()
        {
            Current++;
            return true;
        }

        public void Reset()
        {
            Current = 0;
        }

        public int Current { get; private set; }

        object IEnumerator.Current
        {
            get { return Current; }
        }
    }
}
公共类无穷序列:IEnumerable
{
公共IEnumerator GetEnumerator()
{
返回新的InfiniteNumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
返回GetEnumerator();
}
类无穷枚举器:IEnumerator
{
公共空间处置()
{
抛出新的NotImplementedException();
}
公共图书馆
{
电流++;
返回true;
}
公共无效重置()
{
电流=0;
}
public int Current{get;private set;}
对象IEnumerator.Current
{
获取{返回当前;}
}
}
}

如果它没有做任何其他事情,请继续。专门的集合用于需要执行以下操作的集合。。。特殊的事情


(例如,
ListViewItemCollection
在更新时必须通知其父级
ListView
,因此它需要实现
IList(T)
,因此
IEnumerable(T)
。如果有自定义集合,它可能会从该集合继承。仅从
IEnumerable(T)继承)
只有当您的集合可以枚举,但不能索引时才有意义。)

如果它不做任何其他事情,请继续。专门的集合用于需要执行以下操作的集合。。。特殊的事情

(例如,
ListViewItemCollection
在更新时必须通知其父级
ListView
,因此它需要实现
IList(T)
,因此
IEnumerable(T)
。如果有自定义集合,它可能会从该集合继承。仅从
IEnumerable(T)继承)
只有当您的集合可以枚举,但不能索引时才有意义。)

public class CustomerCollection : List<Customer> // at this time, you have all methods from List such as Add, Remove, [index] etc...
{
   public double AverageAge()
   {
       return this.Average(customer => customer.Age)
   }

   // other methods...
}