texto - Escritura implícita y explícita con nombre de C#6
texto explícito e implicito ejemplos (2)
Una de las características nuevas más prácticas de C # 6 es nameof
, que permite al programador eliminar efectivamente el uso de cadenas mágicas .
Según la documentación, nameof
devuelve una cadena:
Se utiliza para obtener el nombre de cadena simple (no calificado) de una variable, tipo o miembro.
Eso funciona bien con la escritura explícita en el siguiente ejemplo de código:
string magicString = nameof(magicString);
Sin embargo, cuando se utiliza la escritura implícita con la palabra clave var
:
var magicString = nameof(magicString);
el compilador arroja un error:
No se puede usar la variable local ''magicString'' antes de que se declare
Luego realicé más experimentos con la ventana interactiva de C # disponible en Visual Studio. Nuevamente, el primer ejemplo funcionó bien, pero el segundo ejemplo arrojó un error diferente esta vez:
error CS7019: El tipo de ''magicString'' no se puede inferir ya que su inicializador se refiere directa o indirectamente a la definición.
La expresión nameof
claramente devuelve una cadena, así que ¿por qué el compilador no puede escribirla implícitamente cuando se usa con la variable inicializada?
El equipo de idiomas sintió que esto no valía la complejidad de la especificación.
Puedes ver la discusión github.com/dotnet/roslyn/issues/766 .
La razón subyacente de este comportamiento es que la especificación dice (§8.5.1) que los nombres declarados con var
no son visibles en la declaración de declaración, ya que antes de nameof
, no había forma en que pudiera ser válido.
Las declaraciones de variables locales implícitamente escritas están sujetas a las siguientes restricciones:
- ...
- La expresión inicializadora no puede referirse a la variable declarada
Sin var
, declaraciones como int x = x = 1;
o int x = 1, y = x;
son legales con var
, nada en esa forma es válido.
La capacidad de declarar una variable y asignarla en la misma declaración es azúcar sintáctica. Por ejemplo, cuando dices esto:
string magicString = nameof(magicString);
lo que realmente estás diciendo es esto:
string magicString;
magicString = nameof(magicString);
Como magicString
ya está declarado, puede usarlo en la siguiente declaración lógica como parte del operador naemof
. Esto se debe a que magicString
ahora es parte del alcance que es visible para las declaraciones posteriores.
Ahora, lo anterior no es cierto cuando se usa var
porque todo lo que usa var
para hacer una asignación es realmente parte de una sola declaración, no de azúcar sintáctica para dos declaraciones como el ejemplo anterior. La variable magicString
realidad no se declara hasta después de la función llamada / operador / asignación, por lo tanto, la variable no es parte del alcance hasta que haya realizado la asignación, es decir, en la (s) siguiente (s) declaración (es).
SLaks se refirió a github.com/dotnet/roslyn/issues/766 , pero lo que se señala en las notas de esta reunión posterior del equipo de diseño de C # sobre este tema en la pregunta de "¿Debería var x = nameof (x) trabajar?":
Esto funciona de la misma manera que con cualquier otra construcción, es decir: no. Este no es un caso especial para nameof, y no parece que valga la pena una carcasa especial para permitirlo.
En otras palabras, no es específico de nameof
.