寻找一种更优雅的DO WHILE解决方案

5

我有一些围绕do while循环的代码。

string token;
var count = 0;      
var checkDataLength= data.Length == 16;

do
{              
    count = 0;
    token = GenerateToken(data, start, end);

    if (checkDataLength)
    {
        if (Mod120Check(token))
        {                      
            count += 1;
        }
    }

    if (IsCompliant(token))
    {
        count += 1;
    }
} 
while (count > 0);

return token;

基本上,我正在生成一个令牌,为了使这个令牌有效,必须FAIL Mod120Check和IsCompliant检查。 我无法更改这些方法返回的数据。

虽然上面的代码可以工作,但我觉得很丑陋,想知道有没有更好的方法?

谢谢


我觉得这是最好的方式。其他方案会更加丑陋。它符合您的要求,即至少执行一次。 - Mohit Rustagi
1
我对这段代码没有任何不好的看法。唯一需要改进的是使用 count 变量。它根本不是一个计数器!应该使用一个简单的布尔标志。 - Alejandro
@Alejandro,我觉得Nathalia的回答让这段代码看起来相当糟糕 :) - Max
丑陋的循环通常可以通过 for (;;) {} + break 来修复。显式的 break 使得推理流程和调试中断条件变得容易。在这种情况下,您可能也会喜欢使用 continue。一些程序员可能认为 for (;;) 太刺耳了,但没有什么比它更能表达永远循环的含义了 :) - Hans Passant
2个回答

17

试试这个:

do
{
    token = GenerateToken(data, start, end);
} 
while (checkDataLength && Mod120Check(token) || IsCompliant(token))

将您的条件移到while中。

(!)请注意,只有在checkDataLength && Mod120Check(token)返回false时才会调用IsCompliant(token)。 它不应该引起任何副作用,但这取决于您的IsCompliant方法执行了什么操作。


2
更加整洁!OP可能需要注意,在Mod120Check通过的情况下,原始代码仍然调用IsCompliant,而这个重写不会。这几乎肯定是重写的另一个优点,但值得指出的是,如果该调用具有某些怪异的副作用或其他问题,则需要注意。 - Joe Farrell
@JoeFarrell 好观点!我没有注意到这个细节。已将其添加到答案中。 - Nathalia Soragge

2
你说得对,这很丑。您是以意外的方式使用“count”(它在每个循环的顶部被重置为零,并且可以由于两种不同的原因变为正数)。当我看到“count”时,我期望有些东西从零开始计算并逐渐增加(或从高处开始计算并逐渐减少)。请尝试以下更改:
  • 将“var count = 0;”改为“var goodEnough = false;”,放在最上面
  • 删除“count = 0;”语句
  • 将两个“count +=1;”语句改为“goodEnough = true;”
  • 将“while(count > 0);”更改为“while(!goodEnough);”
这强调了您从“不够好”的状态开始,并会循环直到某个条件使其足够好以继续循环。

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