c# c#-7.0

C#7: subrayado(_) y estrella(*) en la variable de salida



c#-7.0 (4)

Estaba leyendo sobre nuevas características variables en C # 7 here . Tengo dos preguntas:

  1. Dice

    También permitimos los "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 nueva característica de C # 7 porque también podemos hacerlo en pre C # 7.0:

    var _; if (Int.TryParse(str, out _)) ...

    o me estoy perdiendo algo aquí?

  2. 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?


Para los más curiosos

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.


Otro ejemplo del Operador de descarte _ en C # 7 es hacer coincidir un patrón con una variable de tipo object en una instrucción 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 ... _ .


Sobre la primera pregunta

Supongo que esto es solo una información y no una nueva característica de C # 7 porque también podemos hacerlo en pre C # 7.0.

var _; if (Int.TryParse(str, out _)) // ...

La novedad es que ya no tiene que declarar _ dentro o fuera de la expresión y simplemente puede escribir

int.TryParse(s, out _);

Intenta hacer este liner pre C # 7:

private void btnDialogOk_Click_1(object sender, RoutedEventArgs e) { DialogResult = int.TryParse(Answer, out _); }


Discards , en C # 7, se pueden usar siempre que se declare una variable para, como su nombre indica, descartar el resultado. Por lo tanto, se puede usar un descarte 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 introduce ninguna variable _ . Solo se utilizan dos casos de descarte.

Sin embargo, si existe un identificador _ en el ámbito, no se pueden usar 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 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 descartes, pero se abandonó a favor de _ debido a que esta última es una notación más utilizada en otros idiomas .