C#允许双分号; ; 如果是的话,有什么特别的方法吗?

15 .net c#

我正在编写一个声明并编译,但编译器[VS]从未告诉我我将分号放了两次.

这意味着在ASP.NET MVC 3中

return Json(mydata);;

return Json(mydata);
Run Code Online (Sandbox Code Playgroud)

他们都编译,但第一个是错误的设计模式.为什么不告诉我这两个分号.

如果没有理由使用两个分号,为什么不显示错误?

如果有特殊用途,请告诉我在C#中写一个语句需要两个分号的位置.

Jon*_*eet 19

不,从不需要双分号.我有点惊讶的是,编译器没有抱怨它是一个无法访问的语句,但显然它是合法的.它不会造成任何伤害,但同样也不是一个好主意.

  • 为什么它,它是完全可达的,只是空的 (2认同)
  • @Stook:无条件返回语句后如何到达?尝试在其中放置任何其他语句(例如,变量声明),编译器会发出警告。 (2认同)
  • @Bradley:我没有得到Microsoft C#4编译器实现来警告它:( (2认同)

Joe*_*Joe 7

空语句在所有C派生语言中都有效.最常见的习惯用法是在for语句中,例如:

for (; ; )
{
}
Run Code Online (Sandbox Code Playgroud)

如果它们是特殊用途,那么告诉我在c#中写一个语句需要两个分号的位置

在上面的例子中,当然需要两个分号.

  • 为什么不使用 while(true) 循环呢? (2认同)

Bin*_*ier 5

;;允许双重身份是出于历史原因。它是 C 风格语言(C# 所基于的)的宿醉。

C & C++ 有预处理器宏的概念,在编译代码之前在代码中替换它们,例如简单的例子AddAndSquare是一个宏,而不是一个函数

#define AddAndSquare(X,Y) (X+Y)*(X+Y)
int Foo() {
   int a = 1, b = 2;
   return AddAndSquare(a, b);
}
Run Code Online (Sandbox Code Playgroud)

转到编译器作为

int Foo() {
   int a = 1, b = 2;
   return (A+B)*(A+B);
}
Run Code Online (Sandbox Code Playgroud)

您可以重新定义宏以使其与其初始定义不同,也可以重新定义它们,使它们根本不存在。

给定一个断言宏,#define ASSERT(c) if(!c) throw new AssertionFailedException() 你可以让你的代码散落着 ASSERT 语句。

void Foo(int x) {
    int y = x + 2;
    ASSERT(y != 0);
   int z = x / y;
    . . . .
}
Run Code Online (Sandbox Code Playgroud)

现在考虑您只想要调试版本中的断言,而不是发布版本中的断言,对于发布,您将宏重新定义为空(字面意思#define ASSERT)。现在,当 Foo 进入编译器进行发布构建时,它看起来像这样

void Foo(int x) {
    int y = x + 2;
    ;
   int z = x / y;
    . . . .
}
Run Code Online (Sandbox Code Playgroud)

现在 ASSERT 所在的位置有一个空语句,因为那里可能有也可能没有语句(取决于构建配置),编译器需要能够处理空语句。

为什么这个约定保留在 C# 中,没有像C宏一样的东西,我不知道,但可能是因为它造成的危害很小或没有危害。

我猜想;编译器在开始解析代码之前会;忽略多个,因此编译器会忽略您无法访问的内容。