C# 我可以有一个返回 IEnumerator 的方法吗 并在 foreach 循环中使用它?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3315/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I have a method returning IEnumerator
提问by littlecharva
I need to set the height of every textbox on my form, some of which are nested within other controls. I thought I could do something like this:
我需要设置表单上每个文本框的高度,其中一些嵌套在其他控件中。我以为我可以做这样的事情:
private static IEnumerator<TextBox> FindTextBoxes(Control rootControl)
{
foreach (Control control in rootControl.Controls)
{
if (control.Controls.Count > 0)
{
// Recursively search for any TextBoxes within each child control
foreach (TextBox textBox in FindTextBoxes(control))
{
yield return textBox;
}
}
TextBox textBox2 = control as TextBox;
if (textBox2 != null)
{
yield return textBox2;
}
}
}
Using it like this:
像这样使用它:
foreach(TextBox textBox in FindTextBoxes(this))
{
textBox.Height = height;
}
But of course the compiler spits its dummy, because foreachexpects an IEnumerablerather than an IEnumerator.
但当然编译器会吐出它的假人,因为foreach需要一个IEnumerable而不是IEnumerator。
Is there a way to do this without having to create a separate class with a GetEnumerator()method?
有没有办法做到这一点,而不必使用GetEnumerator()方法创建单独的类?
采纳答案by David Wengier
As the compiler is telling you, you need to change your return type to IEnumerable. That is how the yield return syntax works.
正如编译器告诉您的,您需要将返回类型更改为 IEnumerable。这就是 yield return 语法的工作原理。
回答by Yaakov Ellis
// Generic function that gets all child controls of a certain type,
// returned in a List collection
private static List<T> GetChildTextBoxes<T>(Control ctrl) where T : Control{
List<T> tbs = new List<T>();
foreach (Control c in ctrl.Controls) {
// If c is of type T, add it to the collection
if (c is T) {
tbs.Add((T)c);
}
}
return tbs;
}
private static void SetChildTextBoxesHeight(Control ctrl, int height) {
foreach (TextBox t in GetChildTextBoxes<TextBox>(ctrl)) {
t.Height = height;
}
}
回答by Joseph Daigle
If you return IEnumerator, it will be a different enumerator object each time call that method (acting as though you reset the enumerator on each iteration). If you return IEnumerable then a foreach can enumerate based on the method with the yield statement.
如果您返回 IEnumerator,则每次调用该方法时它将是一个不同的枚举器对象(就像您在每次迭代时重置枚举器一样)。如果您返回 IEnumerable,则 foreach 可以根据使用 yield 语句的方法进行枚举。
回答by Orion Edwards
Just to clarify
只是为了澄清
private static IEnumerator<TextBox> FindTextBoxes(Control rootControl)
Changes to
更改为
private static IEnumerable<TextBox> FindTextBoxes(Control rootControl)
That should be all :-)
这应该是全部:-)
回答by supercat
If you are given an enumerator, and need to use it in a for-each loop, you could use the following to wrap it:
如果您有一个枚举器,并且需要在 for-each 循环中使用它,您可以使用以下内容来包装它:
静态公共类 enumerationHelper { 公共类 enumeratorHolder<T> { 私有 T 枚举器; public T GetEnumerator() { return theEnumerator; } public enumeratorHolder(T newEnumerator) { theEnumerator = newEnumerator;} } 静态 enumeratorHolder<T> toEnumerable<T>(T theEnumerator) { return new enumeratorHolder<T>(theEnumerator); } 私有类 IEnumeratorHolder<T>:IEnumerable<T> { 私人 IEnumerator<T> theEnumerator; 公共 IEnumerator<T> GetEnumerator() { return theEnumerator; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return theEnumerator; } 公共 IEnumeratorHolder(IEnumerator<T> newEnumerator) { theEnumerator = newEnumerator; } } 静态 IEnumerable<T> toEnumerable<T>(IEnumerator<T> theEnumerator) { return new IEnumeratorHolder<T>(theEnumerator); } }
The toEnumerable
method will accept anything that c#or vbwould regard an acceptable return type from GetEnumerator
, and return something that can be used in foreach
. If the parameter is an IEnumerator<>
the response will be an IEnumerable<T>
, though calling GetEnumerator
on it once will likely yield bad results.
该toEnumerable
方法将接受c#或vb认为可接受的返回类型的任何内容GetEnumerator
,并返回可在foreach
. 如果参数是 an ,IEnumerator<>
则响应将是 an IEnumerable<T>
,尽管调用GetEnumerator
它一次可能会产生不好的结果。