gpt4 book ai didi

c# - 为什么我们需要两个接口(interface)来枚举一个集合?

转载 作者:太空狗 更新时间:2023-10-29 20:12:42 24 4
gpt4 key购买 nike

很长一段时间以来,我一直在努力理解 IEnumerableIEnumerator 背后的思想。我阅读了所有我能在网上找到的问题和答案,尤其是在 StackOverflow 上,但我并不满意。我已经明白如何应该使用这些接口(interface),但不是为什么以这种方式使用它们。

我认为我误解的本质是我们需要两个接口(interface)来进行一个操作。我意识到如果两者都需要,那么一个可能是不够的。所以我采用了 foreach 的“硬编码”等效项(正如我发现的 here ):

while (enumerator.MoveNext())
{
object item = enumerator.Current;

// logic
}

并试图让它与一个界面一起工作,认为会出现问题,这会让我理解为什么需要另一个界面。

所以我创建了一个集合类,并实现了IForeachable:

class Collection : IForeachable
{
private int[] array = { 1, 2, 3, 4, 5 };
private int index = -1;

public int Current => array[index];

public bool MoveNext()
{
if (index < array.Length - 1)
{
index++;
return true;
}

index = -1;
return false;
}
}

并使用 foreach 等效于指定集合:

var collection = new Collection();

while (collection.MoveNext())
{
object item = collection.Current;

Console.WriteLine(item);
}

而且有效!那么这里缺少什么需要另一个接口(interface)?

谢谢。


编辑:我的问题与评论中列出的问题不重复:

  • This问题是为什么首先需要接口(interface)来进行枚举。
  • This问题和this问题是关于什么这些接口(interface)以及应该如何使用它们。

我的问题是为什么它们是这样设计的,而不是它们是什么,它们是如何工作的,以及我们为什么需要

最佳答案

这两个接口(interface)是什么,它们的作用是什么?

IEnumerable 接口(interface)位于集合对象上并定义了 GetEnumerator() 方法,该方法返回一个(通常是新的)对象,该对象实现了 IEnumerator 接口(interface)。 C# 中的 foreach 语句和 VB.NET 中的 For Each 语句使用 IEnumerable 访问枚举器,以便循环遍历集合中的元素。

IEnumerator 接口(interface)本质上是放置在实际执行迭代的对象上的契约。它存储迭代的状态并在代码在集合中移动时更新它。

为什么不让集合也成为枚举器呢?为什么要有两个独立的界面?

没有什么可以阻止在同一个类上实现 IEnumerator 和 IEnumerable。然而,这样做有一个代价——不可能在同一个集合上同时有两个或更多的循环。如果可以绝对保证永远不需要同时循环两次集合,那很好。但在大多数情况下这是不可能的。

什么时候有人会一次多次迭代一个集合?

这里有两个例子。

第一个例子是在同一个集合中有两个相互嵌套的循环。如果集合也是枚举器,那么就不可能在同一集合上支持嵌套循环,当代码到达内部循环时,它将与外部循环发生冲突。

第二个例子是当有两个或多个线程访问同一个集合时。同样,如果集合也是枚举器,则不可能在同一集合上支持安全的多线程迭代。当第二个线程尝试遍历集合中的元素时,两个枚举的状态将发生冲突。

此外,由于 .NET 中使用的迭代模型不允许在枚举期间更改集合,否则这些操作是完全安全的。

-- 这是我多年前写的一篇博文:https://colinmackay.scot/2007/06/24/iteration-in-net-with-ienumerable-and-ienumerator/

关于c# - 为什么我们需要两个接口(interface)来枚举一个集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43135556/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com