【问题标题】:why do some lines not have semicolon in C#?为什么有些行在 C# 中没有分号?
【发布时间】:2015-01-04 09:01:04
【问题描述】:

我只是想弄清楚为什么在下面的某些行不以分号结尾但其他行以分号结尾的技术原因 - C# 在某些行中期望的分号是什么,然后在其他行中......

事实上,在写这篇文章时,我注意到必须有大括号 {} 的语句不需要分号,但在它自己的 "Console.WriteLine" 上的行确实需要它。

真的想找出技术原因……

即:

namespace checkPackage     **//no semicolon**
{
    class Program      **//no semicolon**
    {
        static void Main(string[] args)     **//no semicolon**
        {
            listFilesInDirectory(@"C:\Temp\");    **//NEEDS a semicolon**
        }

        static void listFilesInDirectory(string workingDirectory)   **//no semicolon**
        {
            string[] filePaths = Directory.GetFiles(workingDirectory);  **//NEEDS a semicolon**

            foreach (string filePath in filePaths)   **//no semicolon**
            {
                Console.WriteLine(filePath);  **//NEEDS a semicolon**
            }

        }
    }
}

【问题讨论】:

  • 对于 1 放置行尾有点随意。代码块 { code here } 也不需要分号。
  • 质疑现状没有任何问题。答案是显而易见的,语言创造者通过陈述创造了这种“前进的道路”。
  • 因为“线”这个词几乎肯定不会出现在正式的 C# 语言规范中。只有玩具语言才有台词。
  • 注意:不仅限于 C#。大多数使用分号的语言都是这样做的:PHP、C、C++、Java 等......
  • 不要忘记,在最后两行中,您可以有一个可选的分号。所以以class_declaration 结尾的} 和以namespace_declaration 结尾的} 后面可以跟一个分号。但是,结束方法体等的}后面不能跟分号!结束一个块的} 不以分号结尾,但如果你放一个,它将变成一个empty_statement,这是允许的。例如if (b) { M(); };,最后一个分号是empty_statement

标签: c#


【解决方案1】:

分号不是 line 终止符...它是 statement 终止符。每个表达式语句和声明语句的末尾都有一个分号。

iffor 等语句不是表达式或声明语句。)

例如:

public class Foo // Part of a class declaration
{
    int x = 0; // Declaration statement

    public void Bar() // Part of a method declaration
    {
        Console.WriteLine(x); // Expression statement (using an invocation expression)
    } // End of the method declaration, but not a declaration statement 

} // End of class declaration, but not a declaration statement

要求它们的目的是让编译器知道您何时想要结束语句而不是继续下一行:

 int x = 5;
 int y = x // This isn't the end of the statement!
         + 5; // This is...

另一种选择(例如 VB 使用的)是有一个续行,即使当前行是一个有效的语句,您也希望明确地继续到下一行。

如 cmets 中所述,do 语句在这里是异常的。我看不出这不应该是有效的明显原因:

do { } while (false)

...但事实并非如此。 可能与普通的 while 语句需要语句体这一事实有关,例如while (true);(空语句)或while (true) {}(块语句)。我能来的最接近的是“因为 C# 规范说 do 语句末尾需要一个分号......”

【讨论】:

  • do {} 循环怎么样?
  • 那么,do {} 循环呢?我还是很好奇。 :)
  • @Neolisk:没有while 就没有do 这样的东西,一方面。不过请查看我的编辑。
  • +1 在 JavaScript 中使用了更多“替代”分号方法 - 分号会在编译器认为有用的地方自动插入,而且它通常认为只有在分号引入难以找到的错误的情况下才会这样做:) stackoverflow.com/questions/12745743/…
  • @user2023861:它可以,但这只是使用空语句作为循环体。分号属于循环体,而不是作为一个整体来终止for语句。
【解决方案2】:

原因?因为the spec是这么说的:

语句可以由一行代码组成,以 分号或块中的一系列单行语句。一种 语句块括在 {} 括号中,可以包含嵌套 块。

foreach 定义后跟一个语句,该语句必须包含在 {} 中或以分号结尾。这个语句然后被称为循环体。

这可能不足以回答“为什么”这个问题。要深入了解这一点,您确实需要询问设计师。我想,他们想让它接近 C 语法,而不是换行符用于类似目的的其他语言。 (Python iirc)

如果您想要更正式的定义,请download the C# Language Specification 并阅读第 1.2 至 1.5 节。

【讨论】:

    【解决方案3】:

    statements 有两种,简单语句复合语句。循环和方法声明是复合语句。每个简单语句都以分号结尾,但复合语句不以分号结尾。来自msdn

    复合语句由用大括号 ({ }) 括起来的零个或多个语句组成。复合语句可用于任何需要语句的地方。复合语句通常称为“块”。

    花括号指定复合语句的开始和结束。因此编译器查找花括号而不是分号来确定语句的开始和结束。

    【讨论】:

    • 对不起,早上好,我删除了我的评论。
    • 你能解释一下为什么do {} 循环需要分号吗?我认为它与 if 真的没有什么不同......
    • @Neolisk 我认为原因是将do-while循环与常规while循环区分开来。
    • 我认为这在语法上不足以成为这样做的理由。我的猜测是,任何可以有括号的语句都不需要以; 结尾,没有括号的语句必须以分号结尾。我在这里推测,但这是我不介意接受的解释。
    猜你喜欢
    • 2014-09-30
    • 2011-08-25
    • 2023-02-02
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多