使用IEnumerable而不使用foreach循环

Mar*_*ark 35 c# ienumerable yield-return

我必须在这里找到一些简单的东西.

请使用以下代码:

public IEnumerable<int> getInt(){
  for(int i = 0; i < 10; i++){
   yield return i;
  }
}
Run Code Online (Sandbox Code Playgroud)

我可以这样称呼:

foreach (int j in obj.getInt()){
  //do something with j
}
Run Code Online (Sandbox Code Playgroud)

如何在没有foreach循环的情况下使用getInt方法:

IEnumerable<int> iter = obj.getInt();
// do something with iter ??
Run Code Online (Sandbox Code Playgroud)

谢谢.

EDITS

对于那些想知道为什么我想要这个的人.我正在迭代两件事:

IEnumerator<int> iter = obj.getInt().GetEnumerator();
foreach(object x in xs){
  if (x.someCondition) continue;
  iter.MoveNext();
  int n = iter.current();
  x.someProp = n;
  etc...
}
Run Code Online (Sandbox Code Playgroud)

CMS*_*CMS 60

您可以Enumerator使用该GetEnumerator方法获取对该方法的引用,然后您可以使用该MoveNext()方法继续前进,并使用该Current属性访问您的元素:

var enumerator = getInt().GetEnumerator();
while(enumerator.MoveNext())
{
    int n = enumerator.Current;
    Console.WriteLine(n);
}
Run Code Online (Sandbox Code Playgroud)

  • @Anon:像这样:int i = 0; foreach(var x in y){Process(x); 我++; if(i == 5)GoOffAndDoSomethingDifferent(); }.看看那里发生了什么?你处理前几个,然后你去完全做其他事情,然后你回来完成其余的处理."完全去做其他事情,在完成后从你离开的地方拿起"是对我们通常认为是"调用方法"的操作的描述. (8认同)
  • @Anon:你可以用'foreach`做同样的事情. (3认同)
  • 它允许您对前几个元素进行特殊处理,或者在处理多个元素后完全停止等等。基本上,它为您提供了更多的多功能性。 (2认同)
  • 详细说明你如何处理枚举的一些元素,然后完全做其他事情,然后回来并用"foreach"完成其余部分的处理. (2认同)
  • @FitzchakYitzchaki 我时不时使用它的一件事是能够同时枚举多个可枚举项。我不认为你可以使用“foreach”来做到这一点,并且要使用“for”循环来做到这一点,你需要枚举至少是“ICollection”而不是“IEnumerable”。 (2认同)

Eri*_*ert 31

我的建议是:不要乱搞普查员.将您的问题描述为序列上的一系列操作.编写代码来表达这些操作.让序列运算符负责管理枚举器.

所以让我们看看我是否已经做到这一点.你有两个序列.让我们说{2,3,5,7,12}和{"青蛙","蟾蜍"}.你想要执行的逻辑操作是,"通过第一个序列.每次你找到一个可被3整除的数字,得到第二个序列中的下一个项目.用结果(数字,两栖)对做一些事情."

轻松完成.首先,过滤第一个序列:

var filtered = firstSequence.Where(x=>x%3 == 0);
Run Code Online (Sandbox Code Playgroud)

接下来,使用第二个序列压缩过滤后的序列:

var zipped = filtered.Zip(
             secondSequence, 
             (y, z)=> new {Number = x, Amphibian = y});
Run Code Online (Sandbox Code Playgroud)

现在,您可以遍历压缩序列并使用对执行任何操作:

foreach(var pair in zipped)
    Console.WriteLine("{0} : {1}", pair.Number, pair.Amphibian);
Run Code Online (Sandbox Code Playgroud)

简单易玩,没有与调查员混淆.

  • @Mark:(1)人们忘了处理它们.(2)枚举器强调*代码如何工作而不是*它是什么* - 使用枚举器读取代码就像查看钻孔马达的描述,当你想要描述的是产生的孔时.它们当然有时是必要的,但我更愿意在更高的抽象层次上表达我的操作,而不是在必须明确跟踪多个序列中的多个"游标"的操作. (5认同)
  • @Eric,你的方法的一个警告是,如果这是在大量的内存数据上,可能是通过手动迭代两个列表同时性能增益...如果它是少量的数据或性能是然后我会选择优雅的代码(即你的代码)而不是细节代码. (4认同)
  • @Jason:Zip所做的就是分配两个枚举器并运行它们.开销应该很小.记住,序列运算符是懒惰的; 他们没有立刻意识到他们的结果,他们只是按照要求从他们的源序列中提取出来. (3认同)

zil*_*n01 5

这个怎么样?

IEnumerator<int> iter = obj.getInt();
using(iter) {
    while(iter.MoveNext()) {
        DoSomethingWith(iter.Current)
    }
}
Run Code Online (Sandbox Code Playgroud)