IEnumerator和IEnumerable有什么区别?
我正在通过IEnumerable和IEnumerator,但是没有明确地得到一点......如果我们有foreach,那为什么我们需要这两个接口呢?有没有我们必须使用接口的场景.如果是,那么有人可以用一个例子来解释.欢迎任何建议和评论.谢谢.
免责声明:我明白之间的差别IEnumerable<T>,并 IEnumerator<T>和如何使用这两种.这与此或此不重复.
这更像是一个设计问题 - 因为IEnumerator<T>已经封装了可以枚举的所有必要信息(.Current,.MoveNext()),那么引入一个type(IEnumerable<T>)的目的是什么呢?它的唯一目的是返回前者的实例?
再具体一点:
为什么不能foreach设计为直接迭代IEnumerator<T>,如下所示:
// foreach (var e in anEnumerator) { //... }
while (anEnumerator.MoveNext())
{
doSomething(anEnumerator.Current);
}
Run Code Online (Sandbox Code Playgroud)为什么不能直接建立Linq IEnumerator<T>?
这是相当长一段时间,我一直在试图了解背后的想法IEnumerable和IEnumerator.我阅读了网上可以找到的所有问题和答案,特别是StackOverflow,但我并不满意.我明白了我应该如何使用这些接口,但不是为什么这样使用它们.
我认为我误解的本质是我们需要两个接口进行一次操作.我意识到,如果两者都需要,可能还不够.所以我采用了"硬编码"等价物foreach(正如我在这里找到的):
while (enumerator.MoveNext())
{
object item = enumerator.Current;
// logic
}
Run Code Online (Sandbox Code Playgroud)
并试图让它与一个界面一起工作,认为某些事情会出错,这将使我理解为什么需要另一个界面.
所以我创建了一个集合类,并实现了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;
}
}
Run Code Online (Sandbox Code Playgroud)
并使用foreach …
尽管场景奇怪,但这不是一个功课问题.我刚刚替换了我正在使用的真实对象来简化示例.
这让我从这里开始,但不确定如何继续.我试图写一个包含集合类,而我在世界迷路IEnumerator和IEnumerable,这是我很新的(甚至没有完全肯定我是在正确的道路上).假设我有一节课:
Public Class BakedBean
Private Shape As String
Private Variety As String
Private Flavour As String
'etc
End Class
Run Code Online (Sandbox Code Playgroud)
另一个代表BakedBeans 集合的类:
Public Class TinOfBeans
'?
End Class
Run Code Online (Sandbox Code Playgroud)
我希望能够作为一个集合Beans进入TinOfBeans类中,这样我就可以进行这样的调用,但不依赖于特定的集合类型:
Dim myTin As New TinOfBeans()
myTin.Add(New BakedBean(...))
For Each bean As BakedBean in myTin
'...
Next
myTin(0).Flavour = "beany"
Run Code Online (Sandbox Code Playgroud)
我一直在寻找IEnumerable和IEnumerator,我有这么多,到目前为止,但我越来越很失去了它:
BakedBean类
Public Class BakedBean
Private Shape As String
Private Variety As String
Private Flavour …Run Code Online (Sandbox Code Playgroud) 在使用迭代器时yield return,返回IEnumerator和IEnumerable?之间有什么区别?
我正在使用Unity3D的 StartCoroutine 方法,我有一个关于嵌套协程的问题。
通常,嵌套协程可能如下所示:
void Start() { StartCoroutine(OuterCoroutine()); }
IEnumerator OuterCoroutine()
{
//Do Some Stuff . . .
yield return StartCoroutine(InnerCoroutine());
//Finish Doing Stuff . . .
}
IEnumerator InnerCoroutine()
{
//Do some other stuff . . .
yield return new WaitForSeconds(2f);
//Finish Doing that other stuff . . .
}
Run Code Online (Sandbox Code Playgroud)
这一切都很好,但真的没有必要。可以像这样实现相同的效果:
void Start() { StartCoroutine(OuterCoroutine()); }
IEnumerator OuterCoroutine()
{
//Do Some Stuff . . .
IEnumerator innerCoroutineEnumerator = InnerCoroutine().GetEnumerator();
while(innerCoroutineEnumerator.MoveNext())
yield return innerCoroutineEnumerator.Current;
//Finish Doing Stuff . …Run Code Online (Sandbox Code Playgroud) 使用yield return将方法变成迭代器。迭代器的返回类型必须是IEnumerable、IEnumerable<T>、IEnumerator或IEnumerator<T>。
我发现迭代器只能foreach在返回其中一种IEnumerable类型的情况下在循环中使用。考虑到这一限制,什么时候选择IEnumerator返回类型而不是才有意义IEnumerable?
我对C#语言中各种类型之间的差异感到很困惑.特别
在互联网上搜索C#中的IEnumerable接口是什么?它解决的问题是什么?如果我们不使用它怎么办?但从来没有真正得到太多.很多帖子都解释了如何实现它.
我还发现了以下示例
List<string> List = new List<string>();
List.Add("Sourav");
List.Add("Ram");
List.Add("Sachin");
IEnumerable names = from n in List where (n.StartsWith("S")) select n;
// var names = from n in List where (n.StartsWith("S")) select n;
foreach (string name in names)
{
Console.WriteLine(name);
}
Run Code Online (Sandbox Code Playgroud)
上述输出:
Sourav
萨钦
我想知道,在上面的例子中使用IEnumerable的优势是什么?我可以使用'var'(注释行)来实现相同的功能.
如果你们中的任何人可以帮助我理解这一点并且使用IEnumerable的例子有什么好处,我将不胜感激?如果我们不使用它怎么办?
我来自 Python 世界,正在尝试用 C# 创建一个“生成器”方法。我正在以特定缓冲区大小的块解析文件,并且只想一次读取并存储下一个块并在循环中生成它foreach。这是我到目前为止所拥有的(简化的概念证明):
class Page
{
public uint StartOffset { get; set; }
private uint currentOffset = 0;
public Page(MyClass c, uint pageNumber)
{
uint StartOffset = pageNumber * c.myPageSize;
if (StartOffset < c.myLength)
currentOffset = StartOffset;
else
throw new ArgumentOutOfRangeException("Page offset exceeds end of file");
while (currentOffset < c.myLength && currentOffset < (StartOffset + c.myPageSize))
// read data from page and populate members (not shown for MWE purposes)
. . .
}
}
class MyClass …Run Code Online (Sandbox Code Playgroud) 我想知道我们应该使用的确切位置IEnumberable<T>
我知道如何IEnumerable<T>工作和返回IEnumerator<T>以及所有这些,但最终目标IEnumerable<T>是从集合中查询数据不是吗?这就是我们已经可以使用 foreach() 循环做到的事情吗?那么什么时候使用IEnumerable<T>呢?IEnumerable<T>查询集合的唯一选项的实际场景是什么?
c# ×11
ienumerable ×5
.net ×4
ienumerator ×3
collections ×2
foreach ×2
iterator ×2
.net-core ×1
asp.net ×1
c#-4.0 ×1
coroutine ×1
enumeration ×1
enumerator ×1
generator ×1
oop ×1
vb.net ×1