“for(bool flag = true; flag; flag = false){...}” - 这是正常的吗?

时间:2012-02-15 18:01:43

标签: c# for-loop

我从未见过以这种方式初始化的for循环,并且不明白为什么会以这种方式编写?

我正在研究如何在.NET中连接到IMAP服务器,并开始查看名为ImapX的库中的代码。我在一个方法中找到了for循环,该方法将数据写入NetworkStream,然后看起来在时髦的for循环中读取响应。我不想逐字复制和粘贴其他人的代码,但这里是要点:

public bool SendData(string data)
{
  try
  {
    this.imapStreamWriter.Write(data);

    for (bool flag = true; flag; flag = false)
    {
      var s = this.imapStreamReader.ReadLine();
    }
  }
  catch (Exception)
  {
    return false;
  }

  return true;
}

同样,这不是确切的代码,但这是一般的想法。这就是所有方法都做的,它不使用服务器响应,如果没有抛出异常,它只返回true。我只是不明白for循环是如何或为何以这种方式使用的;任何人都可以解释初始化这个优惠有什么好处,如果有的话?

4 个答案:

答案 0 :(得分:5)

这是一次执行循环的可怕方式。如果您将flag initalizer更改为并非总是true,则可能略微更有意义,但不是很多。我之前完全没有建议过这个代码:

Animal animal = ...;
for (Dog dog = animal as Dog; dog != null; dog = null)
{
    // Use dog...
}

...作为一种使用as运算符而不“污染”外部范围的方法。但这是语言愚蠢,而不是我真正使用的东西。

答案 1 :(得分:2)

我以前认为你正在查看原始源代码,但是根据你的评论,听起来你正在看着基于MSIL的Reflector的重构C#。重要的是要理解,这并不一定与所写的原始代码非常相似。

在MSIL级别,没有for循环或while循环。只有条件分支指令。 (参见这里:http://weblogs.asp.net/kennykerr/archive/2004/09/23/introduction-to-msil-part-6-common-language-constructs.aspx)任何试图重构C#的工具都必须对代码最初的结构进行一些猜测。似乎很可能这不是最初编写为for循环,而是Reflector检测到IL 可以for循环生成,并且其启发式错误的猜测它应该是for循环,而不是其他东西。

如果我在ILSpy中查看相同的代码,它将呈现为while循环。它仍然是多余的,但它看起来不那么奇怪。此外,原始代码可能实际上做了一些已经优化的东西,可能调用[Conditional]方法或标有#if指令的代码。然后,也许原来的代码用于做其他事情,但部分被注释掉了 - 评论没有留在IL中。或者也许过去有更多的代码,它只是简单删除。

简而言之,您在Reflector中看到的方法与最初编写的方式有很多不同。您应该将它视为IL的更漂亮的表示,而不是C#的例子,因为它是由人类编写的。

答案 2 :(得分:1)

我将此作为评论,但我想这也是答案。

“循环”毫无意义。它会将flag初始化为true,并声明仅在flag仍为true时执行。但是,flag在第一次迭代后显式设置为false。所以在这种情况下,它保证只运行一次。

我怀疑作者试图确保控制流会在ReadLine()上暂停 - 但无论如何它都会这样做,直到收到用户输入为止。

答案 3 :(得分:0)

正如其他人所指出的那样,for循环几乎是一种无操作。

但是,它做了一件事,可能会或可能不会重要:它引入了命名空间范围。变量s的范围是for循环的主体。退出for循环后s超出范围。您可以通过简单地创建一个块来获得相同的效果,因此:

{
  var s = this.imapStreamReader.ReadLine();
}

这仍然很愚蠢。

不知道原作者试图用这个来完成什么 - 也许是为了确保他的s被摧毁/垃圾收集/处置 - 而不是这种技术会起作用(它不会)