Does C# allow double semicolon ; ; if so, are ther

2019-01-06 23:25发布

问题:

I am writing a statement and it compiles, but the compiler [VS] never tells me that I put the semicolon two times.

This means in ASP.NET MVC 3

return Json(mydata);;

return Json(mydata);

Both of them compile, but the first is wrong in design pattern. Why doesn't it tell me about the two semicolons.

If there is no reason to use two semicolons, why doesn't it show an error?

If there is a special use of it, please show me where two semicolons is required to write a statement in C#.

回答1:

No, a double semi-colon is never required. I'm slightly surprised that the compiler doesn't complain that it's an unreachable statement, but apparently it's legal. It won't do any harm, but equally it's not a good idea.



回答2:

The empty statement is valid in all C-derived languages. The most common idiomatic use is in a for statement, e.g.:

for (; ; )
{
}

if their is a special use of it then show me where two semicolon is required to write a statement in c#

In the above example, two semicolons are required of course.



回答3:

That a double ;; is allowed, is for historical reasons. It's is a hangover from C style languages (which C# is based on).

C & C++ have the concept of pre-processor macros which are replaced in the code before the code is compiled e.g. trivial example AddAndSquare is a macro, not a function

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

goes to the compiler as

int Foo() {
   int a = 1, b = 2;
   return (A+B)*(A+B);
}

You can redefine macros to be different to their initial definition, also you can redefine them so they don't exist at all.

Given an assertion macro #define ASSERT(c) if(!c) throw new AssertionFailedException() you can have your coded littered with ASSERT statements.

void Foo(int x) {
    int y = x + 2;
    ASSERT(y != 0);
   int z = x / y;
    . . . .
}

Now consider that you only want the asserts in debug builds, but not in release builds, for release you redefine the macro to be empty (literally #define ASSERT). Now when Foo goes to the compiler for a release build, it looks like this

void Foo(int x) {
    int y = x + 2;
    ;
   int z = x / y;
    . . . .
}

There's now an empty statement where the ASSERT was, because there may or may not be a statement there (depending on build configuration), the compiler needs to be able to handle an empty statement.

Why this convention was kept in C# where there are nothing like C macros, I have no idea, but possibly because it causes little or no harm.

I would guess that multiple ; are elided by the compiler before it starts parsing code, therefore your unreachable ; is ignored by the compiler.



回答4:

There is a difference between "no reason to use them" and "invalid to use them". Why should the language waste time and effort prohibiting you from doing this, when it's harmless?



回答5:

; - statement separator. Double semicolon contains empty statement, which do nothing.

Using empty statement:

while (Method())
   ;

Or

void F() {
   //...
   if (done) goto exit;
   //...
   exit: ;
}

As you can see, this behavior is correct. But in your example you will have unreachable code with empty statement.



回答6:

At the moment no specific reason to write a double semicolon comes to my mind. As far as I know Visual Studio only complains about semicolons that can lead to a unwanted behavior, like the following snippet:

if (true)
    ;

As the semicolon is an empty instruction, the whole if-clause is rendered useless. The Visual Studio complains about all such constructs (using, for, foreach, and so on) without brackets around them.

So the following code is fine for the VS:

 if (true)
 {
      ;
 }


回答7:

C# compiler does not allow ;; between if and else without braces and compiler will throw error in the below case.

if (condition == true)
                ; ; 
            else
                ;

Compiler Error:

Error   CS1513  } expected  and one warning "Possible mistaken empty statement"

So if you remove one semicolon it will work perfectly(or you need to add braces).