C# C:有什么声明吗?

C# C:有什么声明吗?,c#,foreach,radio-button,C#,Foreach,Radio Button,快速提问,我知道有一个foreach语句可以检查表单中的每个指定控件,但是有一个foreach语句可以在一组相同类型的控件中检查特定控件,或者有一个特定的规范可以在foreach状态中使用来限制它。例如:假设我检查表单上的任何单选按钮是否被选中。如果选中一个,则消息框将显示Hi。我的方法是: foreach (Control rb in this.Controls.OfType<RadioButton>()) { if(((RadioButton(rb)).Checked =

快速提问,我知道有一个foreach语句可以检查表单中的每个指定控件,但是有一个foreach语句可以在一组相同类型的控件中检查特定控件,或者有一个特定的规范可以在foreach状态中使用来限制它。例如:假设我检查表单上的任何单选按钮是否被选中。如果选中一个,则消息框将显示Hi。我的方法是:

foreach (Control rb in this.Controls.OfType<RadioButton>())
{
    if(((RadioButton(rb)).Checked == true)
    {
        MessageBox.Show("Hi");
        return;
    }
}

问题是它会检查所有单选按钮,并查看它们是否被选中。我不想那样。我想让它检查一下是否有人被检查过。有什么方法可以处理这个问题吗?

Linq是你的朋友,使用返回bool的方法,但在幕后,它当然也会循环通过复选框,这只是语法上的糖分

您的所有这些代码:

foreach (Control rb in this.Controls.OfType<RadioButton>())
{
    RadioButton rbs = sender as RadioButton();
    if(rbs.Checked == true)
    {
        MessageBox.Show("Hi");
        return;
    }
}

如果选中至少一个复选框,则上述内容将返回true。

好的,您当前的代码已经执行了该操作。在第一个选中的单选按钮之前,只能枚举集合。您可以使用LINQ将代码缩短为

但是否有任何声明

这听起来像是您想要使用以下内容:

var checkedRadioButtons = this.Controls.OfType<RadioButton>().Where(cb => cb.Checked);
或者如果您只想知道是否至少有一个:

bool isAnyCheckedRadioButton = checkedRadioButtons.Any();
或者您想知道检查了多少:

int countCheckedRadioButtons = checkedRadioButtons.Count();
或者您希望将它们存储在集合中:

List<RadioButton> checkedRadioButtonList = checkedRadioButtons.ToList();

可能是使用Enumerable的LINQ查询。您对任何问题的理解是什么:

您可以创建自己的扩展方法来完成它-这就是ForEach、Select等的全部内容

public static class EnumerableExtensions
{
    public static void ForFirst<T>(this IEnumerable<T> arr, Func<T, bool> predicate, Action<T> action)
    {
        using (var enumerator = arr.GetEnumerator())
        {
            while (enumerator.MoveNext())
            {
                if (predicate(enumerator.Current))
                {
                    action(enumerator.Current);
                    return;
                }
            }
        }
    }
}
用法:

this.Controls.OfType<RadioButton>()
    .ForFirst(
        rb => rb.Checked, 
        rb => MessageBox.Show("Hi from " + rb.ToString()));

您可以使用First,Where,Any,我刚刚提供了一个不同但有效的解决方案。这是一个灵活的解决方案,一个线性

不,您当前的方法仅在找到已检查的radiobutton@TimSchmelter它会检查每个指定的控件吗?您可以编写自己的可枚举扩展,在示例返回的第一个True上执行方法,从而在第一次找到选中的按钮时中断循环。我的猜测是,您的代码实际上并没有检查您循环使用的任何按钮,而是在每次迭代中检查包装为rbs的发送方控件。ForAny=Where+。OP要求使用类似ForAny的方法,而不是foreach,但OP也没有枚举整个集合。他按了第一个勾选的按钮就停了下来。如果他将bool变量anyChecked初始化为true并中断循环,那么在没有LINQ的情况下,他的代码将与您的代码相同。另外,ForAny听起来更像Controls.OfType.Whererb=>rb.Checkedagreed,但OP要求像ForAny一样内置一个方法,所以我们有任何权利:@EhsanSajjad这在foreach语句中也起作用吗?而且,这可能是bool anyChecked而不是var anyChecked吗?您的代码包含与OP的代码相同的打字错误。它不检查rb是否已检查。它正在检查rbs是否被检查。因此,您的LINQ将产生与foreach方法不同的结果。我是否建议改用First或FirstOrDefault?不需要使用rb作为RadioButton,类型的RadioButton应该已经为您这样做了。我同意abion47的说法,不妨先打个电话这看起来很复杂。我不知道我是否能使用或理解它。这很简单,你所做的只是从枚举表中获取枚举数——实际上是迭代列表的东西,然后检查是否可以移动到下一个元素,如果它成功,将更改为当前元素,然后它将调用谓词函数检查条件,如果成功,它将调用动作函数定义要执行的操作,然后返回。@Callumlington我不会怀疑这是否有效,但我对静态类和静态空区一点经验都没有。我不知道如何评估这段代码,因为您没有为我做这件事,也不知道发生了什么,或者如果出现错误,如何修复它。除了使用它循环x次之外,原始代码对集合没有任何作用。除此之外,我认为解决方案是正确的。我无法让这台机器工作。我想这是因为我的单选按钮存储在面板中。我该如何修复它?@BradleyWilliamElko:更好的是,你需要使用:panel.Controls.OfType。。。而不是这个.Controls.OfType…@TimSchmelter我找到了它,但我不明白为什么表单无法检测到它?它的形式仍然是。@BradleyWilliamElko:因为OfType是一个扩展方法,它按类型过滤给定的序列。它不知道控件可以包含子控件。面板是这样一个容器控件,其中包含子控件,即单选按钮。因此,您将永远找不到嵌套在OthersRecursive中的控件。如果使用,即使控件位于另一个子控件中,如果将true作为第二个参数传递,也会按名称查找控件。
List<RadioButton> checkedRadioButtonList = checkedRadioButtons.ToList();
public static class EnumerableExtensions
{
    public static void ForFirst<T>(this IEnumerable<T> arr, Func<T, bool> predicate, Action<T> action)
    {
        using (var enumerator = arr.GetEnumerator())
        {
            while (enumerator.MoveNext())
            {
                if (predicate(enumerator.Current))
                {
                    action(enumerator.Current);
                    return;
                }
            }
        }
    }
}
this.Controls.OfType<RadioButton>()
    .ForFirst(
        rb => rb.Checked, 
        rb => MessageBox.Show("Hi from " + rb.ToString()));