2011-05-16 29 views
8
public void Finalise() 
    ProcessFinalisation(true); 

no compila, pero la versión correcta:¿Por qué los métodos con una sola instrucción necesitan llaves?

public void Finalise() 
{ 
    ProcessFinalisation(true); 
} 

compila bien (por supuesto).

si se me permite, si de sin paréntesis cuando el siguiente código tiene una sola línea:

if(true) 
    CallMethod(); 

¿Por qué es el mismo para los métodos no pueden con una siguiente línea? ¿Hay una razón técnica?

+1

Creo IFS sin corchetes se aconseja en contra, pero está allí por razones históricas. Parece que no puedo encontrar mi fuente en este momento, pero ¿alguien más puede confirmar esto? – Bazzz

+0

"si" es una declaración y esa regla es solo para las declaraciones. Los métodos son los miembros de las clases. –

+0

Tendría que volver a la década de 1970 para encontrar una respuesta. Esto viene de C. –

Respuesta

2

Puesto que C# 6.0 puede declarar:

void WriteToConsole(string word) => Console.WriteLine(word) 

y luego llamar como de costumbre:

public static void Main() 
{ 
    var word = "Hello World!"; 
    WriteToConsole(word); 
} 
14

La respuesta obvia es la especificación del idioma; por el razonamiento ... supongo que principalmente la simplicidad - simplemente no valía la pena la sobrecarga de la cordura - verificar la especificación y el compilador para el minúsculo pequeño número de métodos de declaración única. En particular, puedo ver problemas con restricciones genéricas, etc. (es decir, where T : IBlah, new() al final de la firma).

Tenga en cuenta que no utilizar las llaves puede a veces generar ambigüedades y, en algunos lugares, está mal visto. Soy un poco más pragmático que eso personalmente, pero cada uno es el suyo.

También podría ser de interés que C# dentro de afeitar no permite el uso sin apoyos explícitos. En absoluto (es decir, incluso para if, etc.).

+0

Gracias Marc, ¿tiene un ejemplo en el que no usar llaves forme ambigüedad? –

+3

@Tom - Quiero decir * ambigüedad de * maintenance * - el ejemplo clásico es agregar una segunda instrucción en la misma sangría, sin notar la llave faltante. –

+0

ah te tengo gracias! –

11

Marc tiene básicamente razón. Para ampliar su respuesta un poco: hay una serie de lugares donde C# requiere un bloque de declaraciones reforzado en lugar de permitir una declaración "desnuda". Ellos son:

  • el cuerpo de un método, constructor, destructor, acceso a la propiedad, acceso al evento o accesodor del indexador.
  • bloque de una región de prueba, captura, finalmente, revisada, no marcada o insegura.
  • el bloque de una declaración lambda o método anónimo
  • bloque de una instrucción if o loop si el bloque contiene directamente una declaración de variable local. (Es decir, "mientras (x! = 10) int y = 123;" es ilegal; debe reforzarse la declaración.)

En cada uno de estos casos, sería posible idear una gramática no ambigua (o heurística para eliminar la ambigüedad de una gramática ambigua) para la función en la que una declaración única no vinculada es legal. Pero, ¿cuál sería el punto? En cada una de esas situaciones, usted espera ver múltiples declaraciones; las declaraciones individuales son el caso raro e improbable. Parece que realmente no vale la pena dejar la gramática sin ambigüedades para estos casos muy poco probables.

+0

"el bloque de una declaración lambda" - ¿no es un poco tautológico porque una declaración lambda es una con llaves? – configurator

+1

@configurator: Claro, pero eso es porque así lo decidimos. Una declaración lambda podría ser una lambda donde cualquier declaración sigue a => si quisiéramos. Es más fácil decir que tiene que ser un bloque. "action = x => foreach (var y in x) Console.WriteLine (y);" podría ser una declaración legal lambda si hubiésemos ideado reglas para analizarlo. –

1

Respuesta corta: C# tiene el estilo después de C, y C ordena que las funciones se preparen debido a cómo solían ser las declaraciones de la función C.

versión larga con la historia: De nuevo en K & R C, las funciones fueron declarados como esto:

int function(arg1, arg2) 
int arg1; 
int arg2; 
{ code } 

Por supuesto que no podía tener funciones sin soporte lateral en ese arreglo.ANSI C encomendó a la sintaxis que todos sabemos y amor:

int function(int arg1, int arg2) 
{ code } 

pero no permitió funciones sin soporte lateral, ya que podría causar estragos con los compiladores de edad avanzada que sólo conocían K & R sintaxis [y apoyo para K & declaraciones R fue todavía se requiere].

El tiempo pasó, y años después C# se diseñó en torno a C [o C++, la misma diferencia en términos de sintaxis] y, dado que C no permitió funciones no vinculadas, tampoco lo hizo C#.

Cuestiones relacionadas