在C#中设置int时,逗号运算符/分隔符的机制是什么?

Gri*_*911 3 c# operators comma

我正在分析此stackoverflow问题的接受答案中的代码示例,其中包含以下代码块:

public static void SplitFile(string inputFile, int chunkSize, string path)
{
    const int BUFFER_SIZE = 20 * 1024;
    byte[] buffer = new byte[BUFFER_SIZE];

    using (Stream input = File.OpenRead(inputFile))
    {
        int index = 0;
        while (input.Position < input.Length)
        {
            using (Stream output = File.Create(path + "\\" + index))
            {
                int remaining = chunkSize, bytesRead;
                while (remaining > 0 && (bytesRead = input.Read(buffer, 0,
                        Math.Min(remaining, BUFFER_SIZE))) > 0)
                {
                    output.Write(buffer, 0, bytesRead);
                    remaining -= bytesRead;
                }
            }
            index++;
            Thread.Sleep(500); // experimental; perhaps try it
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

以下一行告诉我一个循环:

int remaining = chunkSize, bytesRead;
Run Code Online (Sandbox Code Playgroud)

我的理解是,与许多C++运算符不同,逗号运算符被故意排除在C#规范之外; 但是,上面的代码编译并运行得很好.

我知道你可以声明多个逗号分隔的变量,如下所示:

int i, j, y;
Run Code Online (Sandbox Code Playgroud)

甚至设置它们

int i = 0, j = 1, y = 2;
Run Code Online (Sandbox Code Playgroud)

但是有问题的行出现在while循环中,并且包含一个(希望)已经声明和初始化的变量,chunkSize以及一个在下面的嵌套while循环中设置的变量bytesRead.所以在多变量声明中使用逗号作为分隔符对我来说并没有多大意义.

在上面的C#代码中,逗号运算符/分隔符的机制和行为是什么?此外,规范中是否有定义这些内容的地方?

Mic*_*tum 6

这是定义两个变量.

int remaining = chunkSize, bytesRead;
Run Code Online (Sandbox Code Playgroud)

相当于

int remaining = chunkSize;
int bytesRead; // uninitialized, gets set to bytesRead = input.Read(buffer,... below
Run Code Online (Sandbox Code Playgroud)

这对我来说有点代码味道,因为同一行中的多个声明难以理解,并且可能给人一种印象,即它之间存在任何连接remaining,bytesRead即使没有.

bytesRead设置为下面一行中的值(input.Read),但有些编译器需要知道bytesRead是一个int.并且C#允许在方法中声明未初始化的变量,只要您在尝试使用它之前初始化它.

  • 当我们设计这个功能时,我对读者进行了一次民意调查,我们还调查了MVP,微软内部人员等等,关于`var x = 10,y = 123.4;`应该是什么的"显而易见的"语义,以及它约为50-50,这是"明显的"含义.所以我们把它弄为非法.一个"便利"功能,总是欺骗一半的专业人士使用它是一个糟糕的功能!https://blogs.msdn.microsoft.com/ericlippert/2006/06/27/what-are-the-semantics-of-multiple-implicitly-typed-declarations-part-two/ (3认同)
  • 哦,伙计,我不敢相信他们允许这样做.阅读起来非常困惑,特别是如果你以前从未见过这个. (2认同)
  • @LewsTherin是的,虽然我想这可能只是解析器如何工作的副作用?`int x,y,z`(三个未初始化的int)和`int x = 0,y = 1,z = 2`是有效的,所以我想也许没有人想过不允许`int x = 0,y, z = 2,v,i,j = 5`. (2认同)
  • @LewsTherin现在,即使初始值匹配,也不允许使用`var`.`var x = 10,y = 20`导致`CS0819隐式类型变量不能有多个声明符 (2认同)
  • @EricLippert说实话,我不知道那行是什么,这就是我启动LINQPad并测试它的原因.冒着听起来像推销员的风险,但购买许可证的价值已经超过了一百万倍,因为任何时候我都想知道"这会做什么?它会起作用吗?" 我可以快速启动linqpad并在30秒内得到答案而不是猜测.(另外,诸如``Path.GetExtension`之类的东西是否包含点,或者其他可以通过运行一些实际代码轻松测试的东西). (2认同)