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:
-
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í?
-
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
.