gpt4 book ai didi

c# - GetIterator() 和迭代器模式

转载 作者:太空宇宙 更新时间:2023-11-03 21:42:50 25 4
gpt4 key购买 nike

我正在尝试实现迭代器模式。基本上,据我了解,它创建了一个类“foreachble”,并通过不向用户透露确切的集合类型来使代码更安全。

我已经做了一些实验,我发现如果我实现在我的类(class)中使用 IEnumerator GetEnumerator(),我得到了想要的结果……似乎避免了为实现接口(interface)而头疼的问题。

这里是我的意思的一瞥:

public class ListUserLoggedIn
{
/*
stuff
*/

public List<UserLoggedIn> UserList { get; set; }

public IEnumerator<UserLoggedIn> GetEnumerator()
{
foreach (UserLoggedIn user in this.UserList)
{
yield return user;
}
}

public void traverse()
{
foreach (var item in ListUserLoggedIn.Instance)
{
Console.Write(item.Id);
}
}
}

我想我的问题是,这是 Iterator 的有效示例吗?如果是,为什么这有效,我该怎么做才能使迭代器通过“var”仅返回一部分或匿名对象。如果不是,正确的方法是什么...

最佳答案

首先是一个更小和简化的独立版本:

class Program
{
public IEnumerator<int> GetEnumerator() // IEnumerable<int> works too.
{
for (int i = 0; i < 5; i++)
yield return i;
}

static void Main(string[] args)
{
var p = new Program();

foreach (int x in p)
{
Console.WriteLine(x);
}
}
}

这里“奇怪”的是 class Program 没有实现 IEnumerable

Ecma-334 的规范说:

§ 8.18 Iterators
The foreach statement is used to iterate over the elements of an enumerable collection. In order to be enumerable, a collection shall have a parameterless GetEnumerator method that returns an enumerator.

这就是为什么 foreach() 在您的类(class)上起作用的原因。没有提到 IEnumerable。但是 GetEnumerator() 是如何产生实现 CurrentMoveNext 的东西的呢?来自同一部分:

An iterator is a statement block that yields an ordered sequence of values. An iterator is distinguished from a normal statement block by the presence of one or more yield statements

It is important to understand that an iterator is not a kind of member, but is a means of implementing a function member

所以你的方法的主体是一个迭代器 block ,编译器检查一些约束(该方法必须返回一个 IEnumerable 或 IEnumerator),然后为你实现 IEnumerator 成员。

对于更深层次的“为什么”,我也学到了一些东西。基于 Eric Lippert 在“The C# Programming Language 3rd”,第 369 页中的注释:

This is called the "pattern-based approach" and it dates from before generics. An interface based approach in C#1 would have been totally based on passing object around and value types would always have had to be boxed. The pattern approach allows

foreach (int x in myIntCollection)

without generics and without boxing. Neat.

关于c# - GetIterator() 和迭代器模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18498344/

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