C# 9.0 – Specification – Target Typing
Índice general – C# 9.0 – Specification
Introducción
Cuando trabajamos con clases y declaramos una instancia de una nueva clase, acostumbramos a indicar la clase, y en el caso de que su constructor tenga parámetros, los parámetros del mismo.
Es decir, tendemos a tener en C# códigos como este:
var person = new Person("Jorge"); System.Console.WriteLine(person.Name); public class Person { public string Name { get; } public Person(string name) { Name = name; } }
Target Typing
Lo que nos permite la nueva característica de C# 9 llamada Target Typing o Target Typed, no es otra cosa que ahorrarnos el indicar el nombre de la clase a instanciar por la derecha.
Pero para ello, por la izquierda no podremos usar var, que resuelve el tipo automáticamente de acuerdo a lo que tiene por la derecha.
Quizás no te quede muy claro explicado con palabras, pero sí te va a quedar claro cuando lo veas escrito en código.
El ejemplo anterior equivalente en C# 9 con la nueva característica del lenguaje quedaría de la siguiente forma:
Person person = new("Jorge"); System.Console.WriteLine(person.Name); public class Person { public string Name { get; } public Person(string name) { Name = name; } }
Observa esta línea de código:
Person person = new("Jorge");
Como podemos observar, hemos indicado la clase en la parte izquierda, pero por la parte derecha, no es necesario, ya que infiere la clase directamente, por lo que podemos indicar simplemente new para pasar sus correspondientes argumentos de su constructor.
Obviamente, indicar el siguiente código, no funcionará correctamente:
var person = new("Jorge");
No podrá inferir la clase y dará un error.
Usando constructor opcionales
Y de igual forma funciona con constructores opcionales.
Es decir, el anterior código con constructores opcionales quedaría de la siguiente forma:
Person person = new(); System.Console.WriteLine(person.Name); public class Person { public string Name { get; } public Person(string name = "") { Name = name; } }
Pero la magia de los argumentos opcionales, nos permite indicar uno de los argumentos en un todo, algo que no es nuevo.
Y de igual modo, es posible utilizarlos con esta característica.
Es decir, el siguiente código sería compatible con lo que indico y aclara lo que estoy tratando de explicar.
Person person = new(age: 18); System.Console.WriteLine($"'{person.Name}' is {person.Age} years old!"); public class Person { public string Name { get; } public int Age { get; } public Person(string name = "", int age = 0) { Name = name; Age = age; } }
Aquí, hemos indicado uno de los argumentos opcionales, en concreto el segundo de ellos, y con la nueva característica de C# 9, usamos new nuevamente.
Menos código, más funcionalidad
Gracias a esta característica, nuestro código puede quedar más simple.
Para muestra, el siguiente botón:
using System; using System.Collections.Generic; List<Person> people = new(); people.Add(new(name: "Jorge", age: 18)); people.Add(new(name: "Mary", age: 19)); foreach (var p in people) Console.WriteLine($"{p.Name} is {p.Age} years old!"); public class Person { public string Name { get; } public int Age { get; } public Person(string name = "", int age = 0) { Name = name; Age = age; } }
Aquí podemos observar cómo la inicialización de una colección y la creación e inicialización de los elementos de esa colección queda simplificada enormemente.
Conclusiones
Aquí entramos en la dicotomía del uso de var introducido en el año 2007 de la mano de C# 3, o bien el uso de esta nueva característica del lenguaje.
No hay nada que sea, a mi juicio, mejor entre las diferentes opciones que tenemos. Quizás se esté añadiendo cierta complejidad al lenguaje aunque ganemos algo de simplificación, pero es bueno conocer que existen diferentes alternativas y que sepamos cómo funcionan cada una.
Happy Coding!