[C#] C# 7. Las nuevas características de nuestro lenguaje favorito.


La verdad es que el equipo de producto de C# está trabajando a un ritmo impresionante. No sólo acabamos de aterrizar en la versión 6 de C# si no que ya se está preparando la versión 7 con nuevas y jugosas mejores características.

Paso a resumir aquellas que para mí son más importantes (por ahora son todas propuestas), las cuales podéis ver en C# 7 Work List of Features #2136

Non-Nullable Reference Types

Como todos sabemos los valores Nullables se introdujeron en la versión 2.0 de .NET Framework (ver Using Nullable Types (C# Programming Guide)). Un tipo por referencia Non-Nullable es justamente lo contrario, se garantiza que el tipo NO puede ser null.

Supongamos que por diseño de nuestra aplicación tenemos una clase que no debe ser nula bajo ningún concepto, en nuestro código deberemos comprobar siempre que el objeto de esa clase NO sea nulo, ese objeto es Mandatory  u obligatorio. Esto hace que se escriban más lineas de código para ello, con lo que el rendimiento de nuestra aplicación puede verse afectado.

Cuando declaramos un tipo como Nullable empleamos el carácter ‘?‘  por lo que para mantener una coherencia se propone el carácter ‘!‘ para declarar un tipo como Non-Nullable.

Veamos un ejemplo de todo esto que acabamos de explicar.

MiClase miClase; // Nullable reference type
MiClase! miClaseMandatory; // Non-nullable reference type

miClase = null; // OK
miClaseMandatory = null; // Error. miClaseMandatory NO puede ser null
miClaseMandatory = miClase; // Error. miClaseMandatory NO puede ser null, miClase SI puede ser null

WriteLine(miClaseMandatory.ToString()); // OK
WriteLine(miClaseMandatory.ToString()); // Warning! miClaseMandatory puede ser null!

if (miClase != null) // Chequear que NO sea null
   WriteLine(miClase.ToString()); // OK 

WriteLine(miClase!.ToString()); // OK

Tuples

La idea principal de uso de esta nueva característica es agrupar temporalmente múltiples valores devueltos por un método.

Actualmente podemos devolver varios valores empleando el la palabra reservada out en la definición de los parámetros de un método.

public void GetPosition(Point point, out double x, out double y)
{
	...
}

Point myPoint = new Point(100, 100);
double x, y;

GetPosition(myPoint, out x, out y);
Console.WriteLine($"X: {x}, Y: {y}");

También se puede emplear el tipo de dato Sytem.Tuple.

public Tuple<double, double> GetPosition(Point point)
{
	...
}

Point myPoint = new Point(100, 100);

var position = GetPosition(myPoint);
Console.WriteLine($"X: {position.X}, Y: {position.Y}");

Podemos definir de tres formas diferentes las nuevas Tuples.

1.- Tuple return types

public (double X, double Y) GetPosition(Point point)
{
	...
}

Point myPoint = new Point(100, 100);
var position = GetPosition(myPoint);

Console.WriteLine($"X: {position.X}, Y: {position.Y}");

2.- Tuple literals

var position = new (double X, double Y) { x = 0, y = 0 };
Console.WriteLine($"X: {position.X}, Y: {position.Y}");

3.- Tuple deconstruction

public (double X, double Y) GetPosition(Point point)
{
	...
}

Point myPoint = new Point(100, 100);
(var x, var y) = GetPosition(myPoint);
Console.WriteLine($"X: {y}, Y: {y}");

Immutable types

Un objeto inmutable es aquél cuyo estado NO puede cambiar después de su creción. Al aplicar este modificador, implícitamente todos los campos son marcados como readonly).

Un ejemplo de esto es el siguiente:

public immutable class Person
{
    public Person(string name, string surName, int age)
    {
        Name = name;
        Surname = surName;
        Age = age;
    }

    public string Name { get; }
    public string Surname { get; }
    public int Age { get; }
}

algo muy chulo es que al emplear el modificador immutable, se puede crear un objeto nuevo basándose en otro:

var person1 = new Person("Sergio", "Parra Guerra", 37);
var person2 = person1 with { Surname = "Guerra Parra" };

Record types

A veces tenemos definidas clases que únicamente contienen propiedades y un constructor. El uso de record type es una forma de abreviar la definición de dichas clases.
En el ejemplo anterior teníamos definida la siguiente clase:

public class Person
{
    public Person(string name, string surName, int age)
    {
        Name = name;
        Surname = surName;
        Age = age;
    }

    public string Name { get; }
    public string Surname { get; }
    public int Age { get; }
}

Que se puede abreviar con la siguiente definición:

public class Person(string Name, string Surname, int Age);

Esta sentencia genera automáticamente:
1.- Un constructor.

public Person(string Name, string Surname, int age)
{
   this.Name = Name;
   this.Surname = Surname;
   this.Age = Age;
}

2.- Generación de propiedades readonly (generación de clase immutable).
3.- Implementación del interfaz IEquatable( GetHashCode, Equals, operator ==, operator !=).
4.- Una implementación por defecto de ToString().
5.- Soporte para Pattern-matching del operador ‘is‘.

Pattern-matching

Los patrones se emplean con el operador is y en un bloque switch para ver sobre qué tipo de dato realizar la comparación.
Un ejemplo de esto es:

Point myPoint = new Point(100, 100);

switch(myPoint)
{
   case string s:
      ...
      break;
   case int i:
      ...
      break;
   case Point(int x, 100) where (Y > 100):
      ...
      break;
   case Point(100, 100): // OK!!!
      ...
      break;
   case 55:
      ...
      break;
   default:
      ...
      break;
}

Para terminar os pongo un enlace de Channel 9 con Mad Torgersen sobre el contenido de este post. Looking Ahead to C# 7 with Mads Torgersen

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s