variable tipo read pattern initialize inicializar crear c# c#-7.0 c#-pattern-matching

tipo - ¿Cuál es el beneficio de los patrones var en C#7?



read var c# (4)

El patrón var se discutió con mucha frecuencia en el repositorio del lenguaje C #, dado que no está perfectamente claro cuál es su caso de uso y dado que is var x no realiza una comprobación nula mientras is T x sí lo hace, por lo que parece bastante inútil.

Sin embargo, en realidad no está destinado a ser usado ya que obj is var x . Está destinado a ser utilizado cuando el lado izquierdo no es una variable por sí solo.

Aquí hay algunos ejemplos de la especificación . Todos usan características que aún no están en C #, pero esto solo demuestra que la introducción del patrón var se hizo principalmente para preparar esas cosas, para que no tengan que volver a tocarlas más tarde.

El siguiente ejemplo declara una función Deriv para construir la derivada de una función utilizando un patrón de coincidencia estructural en un árbol de expresión:

Expr Deriv(Expr e) { switch (e) { // … case Const(_): return Const(0); case Add(var Left, var Right): return Add(Deriv(Left), Deriv(Right)); // … }

Aquí, el patrón var se puede utilizar dentro de las estructuras para "extraer" elementos de la estructura. Del mismo modo, el siguiente ejemplo simplifica una expresión:

Expr Simplify(Expr e) { switch (e) { case Mult(Const(0), _): return Const(0); // … case Add(Const(0), var x): return Simplify(x); } }

Como escribe gafter aquí , la idea también es tener una coincidencia de patrones de propiedad, que permita lo siguiente:

if (o is Point {X is 3, Y is var y}) { … }

No entiendo el caso de uso de patrones var en C # 7. MSDN :

Una coincidencia de patrón con el patrón var siempre tiene éxito. Su sintaxis es

expr is var varname

donde el valor de expr siempre se asigna a una variable local llamada varname . varname es una variable estática del mismo tipo que expr .

El ejemplo en MSDN es bastante inútil en mi opinión, especialmente porque if es redundante:

object[] items = { new Book("The Tempest"), new Person("John") }; foreach (var item in items) { if (item is var obj) Console.WriteLine($"Type: {obj.GetType().Name}, Value: {obj}"); }

Aquí no veo ningún beneficio, podría tener lo mismo si accede directamente al item variable de bucle item que también es de tipo Object . El if es confuso porque nunca es false .

Podría usar var otherItem = item o usar item directamente. ¿Alguien puede explicar mejor el caso de uso?


En la mayoría de los casos es cierto, el beneficio del patrón var no está claro, e incluso puede ser una mala idea. Sin embargo, como una forma de capturar tipos anónimos en la variable temporal funciona muy bien. Esperemos que este ejemplo pueda ilustrar esto: la nota a continuación, agregar un caso nulo evita que var sea siempre nula, y no se requiere ninguna comprobación nula.

var sample = new(int id, string name, int age)[] { (1, "jonas", 50), (2, "frank", 48) }; var f48 = from s in sample where s.age == 48 select new { Name = s.name, Age = s.age }; switch(f48.FirstOrDefault()) { case var choosen when choosen.Name == "frank": WriteLine(choosen.Age); break; case null: WriteLine("not found"); break; }


Lo único que se me ocurre de repente es que si ha escrito dos bloques de código idénticos (en un solo switch ), uno para expr is object a y el otro para expr is null .

Puedes combinar los bloques cambiando a expr is var a .

También puede ser útil en escenarios de generación de código en los que, por cualquier motivo, ya te has escrito en una esquina y siempre esperas generar una coincidencia de patrón, pero ahora quieres emitir un patrón de "coincidir todos".


Sin revisar las notas de diseño en Github, supongo que esto se agregó más por su consistencia con el switch y como un trampolín para casos de emparejamiento de patrones más avanzados,

De la publicación original What''s New in C # 7.0 :

Var patrones de la forma var x (donde x es un identificador), que siempre coinciden, y simplemente coloca el valor de la entrada en una nueva variable x con el mismo tipo que la entrada.

Y el reciente post de disección de Sergey Teplyakov:

Si sabe exactamente lo que está pasando, puede encontrar útil este patrón. Se puede usar para introducir una variable temporal dentro de la expresión: este patrón esencialmente crea una variable temporal utilizando el tipo real del objeto.

public void VarPattern(IEnumerable<string> s) { if (s.FirstOrDefault(o => o != null) is var v && int.TryParse(v, out var n)) { Console.WriteLine(n); } }

La advertencia antes de ese fragmento también es significativa:

No está claro por qué el comportamiento es diferente solo en el modo Release. Pero creo que todos los problemas caen en el mismo grupo: la implementación inicial de la función no es óptima. Pero basado en este comentario de Neal Gafter, esto va a cambiar: "El código de reducción de coincidencia de patrones se está reescribiendo desde cero (también para admitir patrones recursivos). Espero que la mayoría de las mejoras que busque aquí vendrán gratis" "en el nuevo código. Pero pasará algún tiempo antes de que la reescritura esté lista para el horario de máxima audiencia".

Según Christian Nagel :

La ventaja es que la variable declarada con la palabra clave var es del tipo real del objeto,