Estaba leyendo acerca de las nuevas funciones de variables de salida en C#7 aquí . Tengo dos preguntas:
Dice
También permitimos "descartes" como parámetros de salida, en forma de
_, para que pueda ignorar los parámetros que no le interesan:p.GetCoordinates(out var x, out _); // I only care about x
P: Supongo que esto es solo una información y no una característica nueva de C#7 porque también podemos hacerlo en versiones anteriores a C#7.0:
var _; if (Int.TryParse(str, out _)) ...o me estoy perdiendo algo aquí?
Mi código da un error cuando hago lo mencionado en el mismo blog:
~Person() => names.TryRemove(id, out *); * no es un identificador válido. ¿Un descuido de Mads Torgersen, supongo?
Discards , en C#7, se puede usar siempre que se declare una variable, para, como sugiere el nombre, descartar el resultado. Entonces, un descarte se puede usar sin variables:
p.GetCoordinates(out var x, out _);y se puede usar para descartar un resultado de expresión:
_ = 42;En el ejemplo,
p.GetCoordinates(out var x, out _); _ = 42; No se está introduciendo ninguna variable, _ . Solo hay dos casos en los que se utiliza un descarte.
Sin embargo, si existe un identificador _ en el ámbito, no se pueden utilizar los descartes:
var _ = 42; _ = "hello"; // error - a string cannot explicitly convert from string to int La excepción a esto es cuando se usa una variable _ como una variable de salida. En este caso, el compilador ignora el tipo o var y lo trata como un descarte:
if (p.GetCoordinates(out double x, out double _)) { _ = "hello"; // works fine. Console.WriteLine(_); // error: _ doesn't exist in this context. } Tenga en cuenta que esto solo ocurre si, en este caso, se usa out var _ o out double _ . Simplemente use out _ y luego se trata como una referencia a una variable existente, _ , si está dentro del alcance, por ejemplo:
string _; int.TryParse("1", out _); // complains _ is of the wrong type Finalmente, la notación * se propuso al principio de las discusiones sobre los descartes, pero se abandonó en favor de _ debido a que esta última es una notación más utilizada en otros idiomas .
Otro ejemplo del Operador de descarte _ en C# 7 es hacer coincidir el patrón con una variable de tipo object en una declaración de switch , que se agregó recientemente en C# 7:
Código:
static void Main(string[] args) { object x = 6.4; switch (x) { case string _: Console.WriteLine("it is string"); break; case double _: Console.WriteLine("it is double"); break; case int _: Console.WriteLine("it is int"); break; default: Console.WriteLine("it is Unknown type"); break; } // end of main method } Este código coincidirá con el tipo y descartará la variable pasada al case ... _ .
Considere el siguiente fragmento
static void Main(string[] args) { //.... int a; int b; Test(out a, out b); Test(out _, out _); //.... } private static void Test(out int a, out int b) { //... }Esto es lo que está pasando:
... 13: int a; 14: int b; 15: 16: Test(out a, out b); 02340473 lea ecx,[ebp-40h] 02340476 lea edx,[ebp-44h] 02340479 call 02340040 0234047E nop 17: Test(out _, out _); 0234047F lea ecx,[ebp-48h] 02340482 lea edx,[ebp-4Ch] 02340485 call 02340040 0234048A nop ...Como puede ver detrás de escena, las dos llamadas están haciendo lo mismo.
Como señaló @Servé Laurijssen, lo bueno es que no tiene que declarar previamente las variables, lo cual es útil si no está interesado en algunos valores.