C#循环遍历布尔值

9

在C#中是否有一种简洁的方式来循环 true/false 值?

我有大约20行代码在单元测试中,我不想复制来切换一个布尔值的 true/false。

我可以将它拆分成一个函数并调用两次,但是感觉代码更像是迭代可能的值,而不是执行具有不同参数的不同操作。即使我有了一个函数,我也更喜欢循环遍历可能的值的语法,而不仅仅是调用两次。

我可以这样写一个 for 循环...

bool toggle;
for (int i = 0; i < 2; i++)
{
    toggle = i == 1;
}

但这似乎不是很规范。 我喜欢以下语法: 链接
for (bool b : { false, true }) { /* ... */ }

但是它似乎不能在C#中编译。

编辑:

根据Jeroen关于本地函数和Dmitry的答案的建议,我选择了以下路线:

[TestMethod]
public void GetAndSetValue()
{
    foreach (bool toggle in new [] { false, true })
    {
        GetAndSetValue(toggle);
    }

    void GetAndSetValue(bool toggle)
    {
        // details not important
    }
}

有经验的程序员可以就循环和两个函数调用哪个更易读进行辩论:

GetAndSetValue(false);
GetAndSetValue(true);

我更喜欢使用循环,因此我会一直使用它,直到有人抱怨。干杯!

3
在新的 bool 数组 { false, true } 中,对于每个 bool 类型的 b,执行以下操作:{...}。 - Dmitry Bychenko
4
我不明白为什么你认为将这段代码提取到一个独立的函数中是个坏主意。对我来说,按照Dmitry的回答创建循环更加复杂和难以阅读。 - DavidG
2
补充David所说的,不要忘记现代版的C#已经有了本地函数,基本上使提取这样的代码变得免费。对我来说,调用两次函数比“循环每个布尔值”更直观,即使它语义上恰好是你所做的,但这会让我犯二次错,因为通常你不会这样循环。就像循环每个可能的偶素数一样。 - Jeroen Mostert
1
为什么?恐怕我完全不同意这个观点。DoStuff(true)DoStuff(false)for循环看起来更美观。解析循环正在执行的操作所需的认知负荷肯定不值得这样做。 - DavidG
2
我更喜欢循环,所以在有人抱怨之前我会一直使用它。- 我正在抱怨,请停止。 :) - Rand Random
显示剩余6条评论
4个回答

21

正确的语法应该是foreach而不是for

foreach (bool b in new [] { false, true }) {
   /* ... */
}

1
我喜欢它。不如C++版本漂亮。我希望它能够明确地表达出这个循环只会迭代一次“false”和一次“true”的值,以至于没有人会一眼认为,“我可以在这个列表中再添加十个真和假”。但现在我只是在吹毛求疵。:-P - crenshaw-dev
你曾经使用了一个带有 for 循环的编辑器... 那个实现有什么问题? - crenshaw-dev
1
是的,显然应该是for (bool b = false; !b; b = !b)... :-P - Jeroen Mostert
3
优雅与否并不重要,它实际上并没有起作用——它只会生成“false”。使用“for”循环没有简洁的方法来做到这一点。 - Jeroen Mostert
1
for (bool? b = false; b != null; b = (b.Value ? (bool?)null : true)) ... 我知道,这太可怕了。只是忍不住想写一下。 - crenshaw-dev
显示剩余2条评论

4

虽然我认为编写一个参数化函数是正确的方法,但在C#中最接近C++11语法的方法是:

foreach (bool value in new [] { false, true })
{
    // ...
}

1
我可能会这样做,使用本地函数:

[TestMethod]
public void GetAndSetValue()
{
    GetAndSetValue(false);

    void GetAndSetValue(bool toggle)
    {
        // details not important

        if (!toggle)
            GetAndSetValue(true);
    }
}

或者“旧式”的私有方法。
[TestMethod]
public void GetAndSetValue()
{
    GetAndSetValue(false);
}

private void GetAndSetValue(bool toggle)
{
    // details not important

    if (!toggle)
        GetAndSetValue(true);
}

有趣的方法...太糟糕了,参数不能是只读的。一些误导人的人可能会在本地函数中切换 toggle 并意外地终止第二个调用。 - crenshaw-dev
我想这只是让本地函数保持简洁的一个原因。 - crenshaw-dev

0
有点晚来的感觉,但这是我想出来的一个不同的解决方案:
for ((bool b, int n) = (false, 0); n < 2; b = true, n++) {
   /* ... */
}

它适用于C# 7.3,因此与.NET Framework兼容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接