我可以有一个返回 IEnumerator的方法吗? 并在 foreach 循环中使用它?

发布于 2024-07-05 10:30:07 字数 952 浏览 12 评论 0原文

我需要设置表单上每个文本框的高度,其中一些文本框嵌套在其他控件中。 我想我可以做这样的事情:

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;
        }
    }
}

像这样使用它:

foreach(TextBox textBox in FindTextBoxes(this))
{
    textBox.Height = height;
}

但是编译器当然会吐出它的虚拟值,因为 foreach 需要一个 IEnumerable 而不是 IEnumerator< /强>。

有没有一种方法可以做到这一点,而不必使用 GetEnumerator() 方法创建单独的类?

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 foreach expects an IEnumerable rather than an IEnumerator.

Is there a way to do this without having to create a separate class with a GetEnumerator() method?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

淡写薰衣草的香 2024-07-12 10:30:07

正如编译器告诉您的那样,您需要将返回类型更改为 IEnumerable。 这就是yield return 语法的工作原理。

As the compiler is telling you, you need to change your return type to IEnumerable. That is how the yield return syntax works.

放低过去 2024-07-12 10:30:07

只是为了澄清

private static IEnumerator<TextBox> FindTextBoxes(Control rootControl)

对此的更改

private static IEnumerable<TextBox> FindTextBoxes(Control rootControl)

应该是全部:-)

Just to clarify

private static IEnumerator<TextBox> FindTextBoxes(Control rootControl)

Changes to

private static IEnumerable<TextBox> FindTextBoxes(Control rootControl)

That should be all :-)

清醇 2024-07-12 10:30:07

如果返回 IEnumerator,则每次调用该方法时它将是一个不同的枚举器对象(就像在每次迭代时重置枚举器一样)。 如果返回 IEnumerable,则 foreach 可以基于带有yield 语句的方法进行枚举。

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.

娜些时光,永不杰束 2024-07-12 10:30:07
// 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;
    }
}
// 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;
    }
}
花落人断肠 2024-07-12 10:30:07

如果给定一个枚举器,并且需要在 for-each 循环中使用它,则可以使用以下内容来包装它:

static public class enumerationHelper
{
    public class enumeratorHolder<T>
    {
        private T theEnumerator;
        public T GetEnumerator() { return theEnumerator; }
        public enumeratorHolder(T newEnumerator) { theEnumerator = newEnumerator;}
    }
    static enumeratorHolder<T> toEnumerable<T>(T theEnumerator) { return new enumeratorHolder<T>(theEnumerator); }
    private class IEnumeratorHolder<T>:IEnumerable<T>
    {
        private IEnumerator<T> theEnumerator;
        public IEnumerator<T> GetEnumerator() { return theEnumerator; }
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return theEnumerator; }
        public IEnumeratorHolder(IEnumerator<T> newEnumerator) { theEnumerator = newEnumerator; }
    }
    static IEnumerable<T> toEnumerable<T>(IEnumerator<T> theEnumerator) { return new IEnumeratorHolder<T>(theEnumerator); }
}

toEnumerable 方法将接受任何 会将 GetEnumerator 视为可接受的返回类型,并返回可在 <代码>foreach。 如果参数是 IEnumerator<>,则响应将为 IEnumerable,但对其调用 GetEnumerator 一次可能会产生不良结果结果。

If you are given an enumerator, and need to use it in a for-each loop, you could use the following to wrap it:

static public class enumerationHelper
{
    public class enumeratorHolder<T>
    {
        private T theEnumerator;
        public T GetEnumerator() { return theEnumerator; }
        public enumeratorHolder(T newEnumerator) { theEnumerator = newEnumerator;}
    }
    static enumeratorHolder<T> toEnumerable<T>(T theEnumerator) { return new enumeratorHolder<T>(theEnumerator); }
    private class IEnumeratorHolder<T>:IEnumerable<T>
    {
        private IEnumerator<T> theEnumerator;
        public IEnumerator<T> GetEnumerator() { return theEnumerator; }
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return theEnumerator; }
        public IEnumeratorHolder(IEnumerator<T> newEnumerator) { theEnumerator = newEnumerator; }
    }
    static IEnumerable<T> toEnumerable<T>(IEnumerator<T> theEnumerator) { return new IEnumeratorHolder<T>(theEnumerator); }
}

The toEnumerable method will accept anything that or would 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文