Menú de navegaciónMenú
Categorías

La mejor forma de Aprender Programación online y en español www.campusmvp.es

?id=b350e4f7-ca16-4875-80f3-fa82f7f2d3cd

¿Qué son los deconstructores en C# y para qué sirven?

Imagen ornamental. Foto de fondo por @lopezrobin en Unsplash, CC0

Un deconstructor es una forma de transformar una tupla o un objeto en diferentes variables, de forma que dejen de trabajar de manera agrupada. Es decir, nos permite controlar con exactitud cómo podemos "mapear" una tupla o las propiedades de un objeto hacia diferentes variables.

Para ilustrarlo pensemos en un método que devuelve una tupla con dos elementos: nombre y apellidos.

public (string nombre, string apellido) ObtenerDatos()
{
    return ("Rubén", "Rubio");
}

Hasta este momento, si obtenemos el valor devuelto por el método e intentamos mostrarlo por consola, tendríamos que realizar algo como lo siguiente:

var tuplaDesdeMetodo = ObtenerDatos();
Console.WriteLine($"Usuario: {tuplaDesdeMetodo.nombre} {tuplaDesdeMetodo.apellido}");

Pero no tendríamos forma de manejar nombre y apellidos como variables independientes, puesto que es una tupla. Pues precisamente, eso es lo que nos va a permitir la deconstrucción, es decir, que cada elemento pase a una variable independiente.

Para eso tendremos dos opciones:

  1. Declarar explícitamente el tipo de cada variable.
  2. Emplear la palabra reservada var y realizar una declaración implícita.

Por lo tanto podríamos hacer lo siguiente:

// Con declaración explícita
(string nombreExplicito, string apellidoExplicito) = ObtenerDatos();
Console.WriteLine($"Usuario con declaración explícita: {nombreExplicito} {apellidoExplicito}");

// Con declaración implícita
var (nombreImplicito, apellidoImplicito) = ObtenerDatos();
Console.WriteLine($"Usuario con declaración implícita: {nombreImplicito} {apellidoImplicito}");

Como podemos observar, de cualquier manera que lo hagamos, el uso posterior es como si se tratase de variables independientes, siendo el siguiente el resultado de la ejecución:

Deconstrucción

Pero, inicializar variables nuevas para almacenar los valores obtenidos no es la única opción; también podremos realizar una asignación a variables previamente declaradas.

El siguiente código es equivalente al ejemplo anterior, con la salvedad de que en esta ocasión el deconstructor realiza una asignación a variables ya existentes:

string nombre = "";
string apellido = "";

(nombre, apellido) = ObtenerDatos();
Console.WriteLine($"Usuario con asignación: {nombre} {apellido}");

Deconstrucción

Otra posibilidad, disponible con C# 10 o posterior, es la capacidad de mezclar ambas opciones. Es decir, por un lado tendremos valores almacenados mediante la inicialización de variables, mientras que por otro estaremos realizando una asignación en variables preexistentes:

string nombre = "";

(nombre, string apellido) = ObtenerDatos();
Console.WriteLine($"Usuario con asignación y declaración: {nombre} {apellido}");

Deconstrucción en nuestras propias clases

Si queremos ir más allá de las tuplas y dotar de esta capacidad de deconstrucción a nuestras propias clases, también podemos hacerlo. Para eso bastará con añadir un método llamado Deconstruct que no devuelva nada (void). Además, tendrá "n" parámetros de tipo out, que serán los que devuelvan los valores.

Tomemos como ejemplo una clase Alumno con dos propiedades: Nombre y Apellidos. Bastaría con añadir un método Deconstruct quedando como sigue:

public class Alumno
{
    public string Nombre { get; set; }
    public string Apellidos { get; set; }

    public void Deconstruct(out string nombre, out string apellido)
    {
        nombre = Nombre;
        apellido = Apellidos;
    }
}

Posteriormente, si declaramos un objeto de tipo Alumno, podremos llevar a cabo la deconstrucción, obteniendo en este caso dos variables con el nombre y el apellido que contiene el objeto:

Alumno alumno = new Alumno()
{
    Nombre = "Rubén",
    Apellidos = "Rubio"
};

var (nombre, apellido) = alumno;
Console.WriteLine($"Alumno deconstruído: {nombre} {apellido}");

Deconstrucción

Esto es muy útil en ocasiones porque nos permite desestructurar objetos de manera directa, con solo asignarlos, gracias a la deconstrucción.

Deconstrucción de clases ajenas mediante métodos de extensión

Pero ¿qué ocurre en el caso de que nos interese poder deconstruir de esta manera una clase que no sea nuestra, o sea de la que no tengamos acceso a modificar su código?

Por suerte podemos utilizar métodos de extensión, como en otros tantos sitios de la plataforma, para lograr el mismo resultado. En este caso creamos el método extensor Deconstruct tomando como primer parámetro una clase que nos interesa, de la manera convencional para este tipo de métodos.

Por ejemplo, para deconstruir objetos de la clase DateOnly y obtener sus miembros de manera independiente, podemos crear el siguiente método de extensión:

public static class Deconstructores
{
    public static void Deconstruct(this DateOnly fecha, out int anho, out int mes, out int dia)
    {
       anho = fecha.Year;
       mes = fecha.Month;
       dia = fecha.Day;
    }
}

Ahora podríamos utilizarlo de manera directa, así:

DateOnly elFuturo = new(2099,5,23);
(int anhoFuturo, int mesFuturo, int diaFuturo) = elFuturo;
Console.WriteLine([email protected]"El año del futuro es {anhoFuturo},
                  en el mes {mesFuturo},
                  con el día {diaFuturo}");

que nos devolvería por pantalla la cadena:

El año del futuro es 2099,
en el mes 5,
con el día 23
Rubén Rubio Rubén lleva muchos años trabajando como desarrollador de software con diversas tecnologías y certificado por Microsoft desde el año 2003 en desarrollo con .NET. Ha trabajado como analista, desarrollador y responsable de TI en empresas de diferentes sectores. Actualmente trabaja como consultor y desarrollador independiente, ofreciendo sus servicios a empresas e instituciones, siendo también autor y docente en campusMVP. Ver todos los posts de Rubén Rubio
Archivado en: Lenguajes y plataformas

¿Te ha gustado este post?
Pues espera a ver nuestro boletín mensual...

Suscríbete a la newsletter

La mejor formación online para desarrolladores como tú

Agregar comentario

Los datos anteriores se utilizarán exclusivamente para permitirte hacer el comentario y, si lo seleccionas, notificarte de nuevos comentarios en este artículo, pero no se procesarán ni se utilizarán para ningún otro propósito. Lee nuestra política de privacidad.