自定义枚举器的需求点
阅读帖子时,给出了一些要点没有示例:
要实现 IEnumerable / IEnumerable,您必须提供一个枚举器:
•如果该类“包装”另一个集合,则通过返回包装集合的枚举器.
•通过使用yield return 的迭代器。
•通过实例化您自己的 IEnumerator/IEnumerator 实现
(我的幼稚头脑将其解释为)
(Point 1)
If the class is "wrapping" another collection, by returning the
wrapped collection's enumerator.
这意味着..
class StringCollections
{
//A class is wrapping another collection
string[] names=new string {“Jon Skeet”,”Hamish Smith”,
”Marc Gravell”,”Jrista”,”Joren”};
//by returning the wrapped collection’s enumerator
public IEnumerator GetEnumerator( )
{
// What should I return here ?
//like the following ?
yield return names[0];
yield return names[1];
yield return names[2];
....
(or)
foreach(string str in names)
{
yield return str;
}
}
}
(Point 2)
•Via an iterator using yield return.(This point was well explained
by Marc Gravell)
Point 3
By instantiating your own IEnumerator/IEnumerator<T> implementation*
这里第3点代表什么?,因为没有例子,我没有得到那个。 这是否意味着,我可以构建自定义枚举器..(对吗?)。我的问题是,预构建枚举器/枚举器何时足够(作为初学者,我不应该盲目确认这一点) 迭代为什么我应该照顾定制的?一个很好的例子会澄清我的疑问。
感谢您阅读这篇冗长的故事和友善的回复。
When reading a post some points were given without example :
To implement IEnumerable / IEnumerable, you must provide an enumerator :
•If the class is "wrapping" another collection, by returning the wrapped collection's enumerator.
•Via an iterator using yield return.
•By instantiating your own IEnumerator/IEnumerator implementation
(My baby mind interprets it as)
(Point 1)
If the class is "wrapping" another collection, by returning the
wrapped collection's enumerator.
Will it mean ..
class StringCollections
{
//A class is wrapping another collection
string[] names=new string {“Jon Skeet”,”Hamish Smith”,
”Marc Gravell”,”Jrista”,”Joren”};
//by returning the wrapped collection’s enumerator
public IEnumerator GetEnumerator( )
{
// What should I return here ?
//like the following ?
yield return names[0];
yield return names[1];
yield return names[2];
....
(or)
foreach(string str in names)
{
yield return str;
}
}
}
(Point 2)
•Via an iterator using yield return.(This point was well explained
by Marc Gravell)
Point 3
By instantiating your own IEnumerator/IEnumerator<T> implementation*
What does point 3 represent here?,since no example,i did not get that one.
Does it mean,i can build custom enumerator ..(right?).My question here is when prebuild enumerator/enumerators are sufficient (as a beginner i should not blindly confirm this) for
iterations why should i look after the custom one ?Nice example will clarify my doubt.
Thanks for reading this long winded story and kind response.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
(point 1) 您可以将 GetEnumerator 的调用链接到其他集合枚举器:
(point 2) 类似于例如在您的代码中
或将枚举器与逻辑一起放置:
(Point 3) 您想要实现自己的枚举器的情况并不多,但例如您可以寻找一个无限的值集,例如质数:
使用示例可以是:
优点和优点我能想到的缺点:
提前知道所有项目
也很懒所以没必要
计算一个项目,直到它实际上为止
请求的
在 MoveNext 但实际上从
当前财产)。
(point 1) You can chain the call of GetEnumerator to other collection enumerator:
(point 2) Similar to example in your code
Or place enumerator with logic:
(Point 3) There are not many cases where you want to implement your own Enumerator, but for example you can look for an infinite set of values, e.g. prime numbers:
A usage example could be:
Pros & Cons I can think of:
knowing all items in advance
also lazy so there is no need to
compute an item until it's actually
requested
in MoveNext but actually return from
Current property).
这是一个示例:(注意:这是简化的,不是线程安全的示例)
编辑:修复下面由 @Joren 提出的与 Move Previous 将索引值低于 -1 相关的问题。当框架作为 foreach 实现的一部分调用时,MoveNext() 不需要此修复,因为在这种情况下,如果 MoveNext() 返回 false,枚举器实例将终止。但是,如果客户端手动调用 MoveNext(),枚举器将不会终止,因此还需要修复。
另请注意:如何实现这个东西内部的细节取决于你,并且取决于它内部如何管理状态。例如,如果保存引用的 iunternal“bucket”是一个链接列表,而不是 ArrayList,则 MoveNext() 可以通过仅更改 Current 字段以指向旧当前的 nextItem 属性来实现...
Here's an example: (NOTE: This is simplified, not thread safe example)
EDIT: to fix issue raised by @Joren below related to Move Previous taking index value below -1. When called by framework as part of foreach implementation, MoveNext() would not need this fix because in that case if MoveNext() returns false, enumerator instance will terminate. However, if client manually calls MoveNext(), enumerator would not terminate, so it also needs the fix.
Also NOTE: how you implement the details inside this thing is up to you, and will be dependant on how it internally manages state. For example if the iunternal "bucket" that holds the references was a linked list, instead of an ArrayList, then the MoveNext() might be implemented by just changing a Current field to point to the old current's nextItem property...
您所说的 1 实际上适用于 2。
对于 1,它更像是
对于第 3 点,这意味着让 GetEnumerator 做一些实际的工作:手动为您定义的集合实现一个 Enumerator。
What you said for 1 would actually be for 2.
For 1, it'd be more like
For point 3, it'd mean to make GetEnumerator do some real work: Implementing, by hand, an Enumerator for the collection you defined.
“如果该类正在“包装”另一个集合,则通过返回包装的集合的枚举器”意味着:
"If the class is "wrapping" another collection, by returning thewrapped collection's enumerator" means: