变量声明是否应该放在循环之外?

Eri*_*tas 9 .net c# loops variable-declaration

声明在循环外部的循环中使用的变量而不是内部更好吗?有时我会看到在循环中声明变量的示例.这是否有效地导致程序在每次循环运行时为新变量分配内存?或者.NET足够聪明,知道它真的是同一个变量.

例如,请参阅此答案中的以下代码.

public static void CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[32768];
    while (true)
    {
        int read = input.Read (buffer, 0, buffer.Length);
        if (read <= 0)
            return;
        output.Write (buffer, 0, read);
    }
}
Run Code Online (Sandbox Code Playgroud)

这个修改过的版本会更有效吗?

public static void CopyStream(Stream input, Stream output)
{
    int read; //OUTSIDE LOOP
    byte[] buffer = new byte[32768];
    while (true)
    {
        read = input.Read (buffer, 0, buffer.Length);
        if (read <= 0)
            return;
        output.Write (buffer, 0, read);
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 9

不,它不会更有效率.但是,我会以这种方式重写它,无论如何都会在循环之外声明它:

byte[] buffer = new byte[32768];
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
    output.Write(buffer, 0, read);
}
Run Code Online (Sandbox Code Playgroud)

我通常不喜欢在条件中使用副作用,但有效的Read方法是给你两位数据:你是否已经到达流的末尾,以及你读了多少.while循环现在说,"虽然我们设法读取了一些数据......但要复制它."

这有点像使用int.TryParse:

if (int.TryParse(text, out value))
{
    // Use value
}
Run Code Online (Sandbox Code Playgroud)

你再次使用在条件中调用方法的副作用.正如我所说,当你处理一个返回两位数据的方法时,除了这个特殊的模式之外,我没有养成这样的习惯.

同样的事情来自于TextReader:

string line;
while ((line = reader.ReadLine()) != null)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

回到你原来的问题:如果一个变量将在循环的每次迭代中初始化并且它仅在循环体内使用,我几乎总是在循环内声明它.这里的一个小例外是,如果变量被匿名函数捕获 - 此时它会改变行为,我会选择任何形式给我所需的行为......但这几乎总是"声明里面"无论如何.

编辑:当涉及范围界定时,上面的代码确实将变量放在一个比它需要的范围更大的范围内...但我相信它使循环更清晰.如果您愿意,可以通过引入新范围来解决此问题:

{
    int read;
    while (...)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)