Profile Image

Carlos Vigueras

Senior Backend Developer

Refactoring – Records en .Net

En primer lugar, me gustaría comentar que esta entrada la encuadro dentro de Refactoring, ya que a partir de ella podéis aprovechar para refactorizar algunas de vuestras clases y convertirlas a Records.

Los Records existen desde el lanzamiento de C# 9 en noviembre de 2020, hace ya 4 años de esto, pero a pesar de existir hace ya tanto tiempo, su uso no lo he visto muy extendido, al menos en los proyectos que yo he estado implicado, que en 4 años no es que hayan sido muchos, pero tampoco pocos.

Desde mi punto de vista, son muy prácticos de usar, ya que por naturaleza son objetos inmutables, y eso nos ahorra mucho código y lógica de implementación. hasta el punto en el que si no le añadimos ninguna validación, con una sola línea podemos construir un objeto inmutable sin mas complicaciones.

Algo también muy importante es que la igualdad entre dos Records se realiza en base a sus valores, a diferencia de las clases que se realiza en base a sus referencias.

Esto último es importante, pues nos facilita la vida a la hora de realizar los Tests, pero esto lo veremos en otra entrada.

Los Records son definidos así:

Un registro en C# es un tipo de referencia que proporciona una sintaxis simplificada para definir modelos de datos inmutables. A diferencia de las definiciones de clase tradicionales, un registro hace hincapié en la igualdad basada en valores en lugar de en la igualdad de referencias.

Vamos a ver de forma muy rápida y sencilla las diferencias mas esenciales entre las Clases y los Records:

Diferencias clave entre clases y registros

Mutabilidad:

  • Clases : Las clases son mutables de forma predeterminada, lo que permite cambiar las propiedades después de la instanciación a nuestro antojo.

  • Registros : Los registros son inmutables de forma predeterminada, lo que significa que sus propiedades son de solo lectura y se pueden asignar sólo en la inicialización.

Igualdad de Valores:

  • Clases : En una clase necesitamos en algún caso dado la implementación manual de los métodos Equals y GetHashCode necesarios para comprobar la igualdad basada en valores, y estos métodos en muchas ocasiones los he visto implementados sólo para poder utilizarlos en los Tests, y deberíamos saber que generar código productivo sólo para que nos funciones un Test no es correcto.

  • Registros : Los registros implementan por naturaleza propia métodos de igualdad basados ​​en valores, lo que simplifica las comparaciones de valores.

Código:

  • Clases : Escribir clases puede implicar código repetitivo para propiedades, constructores, métodos de igualdad..etc, y además se puede hacer bastante pesado crear una clase inmutable, sobre todo si contiene muchas propiedades.

  • Registros : Los registros son más concisos y generan automáticamente métodos comunes basados ​​en las propiedades.

Vamos a ver un ejemplo de código de un Record, para quien nadie los haya usado y así os pongo mas en contexto:

   public record Person(string Nombre, string Apeliido,
        string Direccion, int Edad, string Sexo);Lenguaje del código: PHP (php)

Un record simplemente se crea de esta forma, y si le incluimos un Test podremos ver como comparando los dos objetos creados el resultado del Test es verde, ya que como he dicho arriba al ser un Record comprueba por valor y no por referencia.

Pero esto no queda aquí, a los Records podemos añadirle validaciones, no tienen por qué quedarse como una simple DataClass sin mas lógica, veamos un ejemplo con una validación:

public record Person(string Nombre, string Apeliido,
    string Direccion, int Edad, string Sexo)
{
    private string _nombre = EsNombreValido(Nombre);
    public string Nombre
    {
        get => _nombre;
        init => _nombre = EsNombreValido(value);
    }

    private static string EsNombreValido(string nombre)
    {
        if(nombre.Length > 10)
            throw new Exception();
        return nombre;
    }
}Lenguaje del código: PHP (php)

En este ejemplo vemos como estamos validando la propiedad Nombre, del objeto Record Person, y si su longitud es mayor que 10 vamos a lanzar una excepción, y a la par estamos respetando la inmutabilidad del objeto.

De esta forma estamos creando un objeto inmutable por naturaleza y estamos realizando una validación sobre una de sus propiedades, por lo que este sería un buen ejemplo a usar con un Value Object, aunque los Value Object los veremos mas detenidamente en otra entrada.

Pues ya está Carlos, si me dices esto, no vuelvo a usar clases, usaré siempre Records!!

Bueno, no exactamente así, no nos tomemos todo al pìe de la letra, los Records los podemos usar en muchísimos casos, pero sobre todo se recomienda usarlos siempre que queramos tener objetos inmutables, pero por favor no siempre, hay muchos casos en los que es mas ventajoso utilizar una clase.

En la próxima entrada os voy a comentar mas en profundidad cuando es recomendable usar Records y por qué.

Espero que os haya sido de ayuda. ¿Vosotros soléis usar Records?

!Os leo en comentarios!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *