在 C# 中设置 int 时,逗号运算符/分隔符的机制是啥?
Posted
技术标签:
【中文标题】在 C# 中设置 int 时,逗号运算符/分隔符的机制是啥?【英文标题】:What are the mechanics of the comma operator/separator while setting an int in C#?在 C# 中设置 int 时,逗号运算符/分隔符的机制是什么? 【发布时间】:2018-07-16 17:58:43 【问题描述】:我正在分析此*** question 的已接受答案中的代码示例,其中包含以下代码块:
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
下面一行让我陷入了循环:
int remaining = chunkSize, bytesRead;
据我了解,与许多 C++ 运算符不同,逗号运算符被故意排除在 C# 规范之外;然而,上面的代码编译并运行得很好。
我知道你可以像这样声明多个逗号分隔的变量:
int i, j, y;
甚至设置它们
int i = 0, j = 1, y = 2;
但有问题的行出现在 while 循环中,并且包含一个(希望)已经声明和初始化的变量 chunkSize
,以及一个在 bytesRead
下面的嵌套 while 循环中设置的变量。所以在多变量声明中使用逗号作为分隔符对我来说真的没有意义。
在上面的 C# 代码中,逗号运算符/分隔符的机制和行为是什么?另外,规范中有没有定义这些东西的地方?
【问题讨论】:
您没有在脑海中正确解析语句。您正确地注意到您可以在声明中使用逗号分隔的变量列表,并且您正确地注意到您可以选择在声明中分配初始值。您还可以混合匹配这两种语法!您可以拥有一个以逗号分隔的声明列表,其中其中一些具有初始化程序,这就是您所拥有的。 现在,这是一个有趣的问题:这是什么意思:var x = 10, y = 123.4;
。这是否意味着:int x = 10; double y = 123.4;
还是意味着 double x = 10, y = 123.4;
。看看你能不能弄明白,然后试试看。你说对了吗?
这与VB中一个著名的设计问题有关,你可以说Dim Curly, Larry, Moe as Stooge
,当然这意味着:Curly
和Larry
是Variant
,Moe
是@987654336 @,这很令人困惑。
@EricLippert 我真的很想念你在编码方面的精彩冒险!
感谢您的客气话。我只是最近没有时间写博客。我希望能重回正轨!
【参考方案1】:
这是定义两个变量。
int remaining = chunkSize, bytesRead;
等价于
int remaining = chunkSize;
int bytesRead; // uninitialized, gets set to bytesRead = input.Read(buffer,... below
这对我来说有点代码味道,因为同一行中的多个声明很难遵循,并且可能会让人觉得 remaining
和 bytesRead
之间存在任何联系,即使没有联系。
bytesRead 被设置为下面一行中的一个值 (input.Read),但是编译器需要知道 bytesRead 是一个 int。而且 C# 允许在方法中声明未初始化的变量,只要您在尝试使用它之前对其进行了初始化。
【讨论】:
天哪,我不敢相信他们允许这样做。阅读起来非常混乱,尤其是如果您以前从未见过。 @LewsTherin 是的,虽然我猜这可能只是解析器工作方式的副作用?int x, y, z
(三个未初始化的整数)和int x = 0, y = 1, z = 2
都是有效的,所以我猜可能没有人考虑过禁止int x = 0, y, z = 2, v, i, j = 5
。
@LewsTherin 现在,var
不允许使用它,即使初始化程序匹配。 var x = 10, y = 20
导致 CS0819 Implicitly-typed variables cannot have multiple declarators
@EricLippert 老实说,我也不知道那条线做了什么,这就是我启动 LINQPad 并对其进行测试的原因。冒着听起来像推销员的风险,但购买许可证值得一百万倍,因为任何时候我都想知道“这会做什么?它甚至会起作用吗?”我可以快速启动 linqpad 并在 30 秒内得到答案,而不是猜测。 (另外,像 Path.GetExtension
这样的东西是否包含点,或者其他可以通过运行一些实际代码轻松测试的东西)。
在设计该功能时,我对读者进行了调查,我们还对 MVP、Microsoft 内部人员等进行了调查,以了解 var x = 10, y = 123.4;
的“明显”语义应该是什么,以及大约是50-50,这是“明显”的意思。所以我们把它定为非法的。一个“方便”的功能总是让一半的专业人士使用它,这是一个糟糕的功能! blogs.msdn.microsoft.com/ericlippert/2006/06/27/…【参考方案2】:
我还认为在同一行中声明多个变量会让人感到困惑和代码异味,尽管语言允许其他东西。
为了在 C# 布局约定中支持这一点,link 声明:
每行只写一个声明。
【讨论】:
以上是关于在 C# 中设置 int 时,逗号运算符/分隔符的机制是啥?的主要内容,如果未能解决你的问题,请参考以下文章
批处理,如何在for 中的 delims 中设置空格和其他字符做分隔符