 
Los records son una interesante fórmula para definir tipos en C# de forma rápida gracias a su concisa sintaxis, además de ofrecer otras ventajas, entre las que destacan la inmutabilidad o la implementación automática de métodos como Equals(), GetHashCode() o ToString().
Por si no tenéis esto muy fresco, aquí va un ejemplo de record y la clase tradicional equivalente en C#:
// Record:
public record Person(string FirstName, string LastName);
// Clase equivalente (generada automáticamente):
public class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }
    public override bool Equals(object obj)
    {
        return obj is Person person &&
               FirstName == person.FirstName &&
               LastName == person.LastName;
    }
    public override int GetHashCode()
    {
        return HashCode.Combine(FirstName, LastName);
    }
    public Person With(string FirstName = null, string LastName = null)
    {
        return new Person(FirstName ?? this.FirstName, LastName ?? this.LastName);
    }
    public void Deconstruct(out string firstName, out string lastName)
    {
        firstName = this.FirstName;
        lastName = this.LastName;
    }
}
Como podéis comprobar, hay pocas características de C# que ofrezcan una relación código/funcionalidad tan bárbara como los records. Por ello, poco a poco van ganando popularidad y comenzamos a verlos ya de forma habitual en código propio y ajeno.
Sin embargo, su concisa sintaxis hacen que a veces no sea fácil intuir cómo resolver algunos escenarios que, usando las clases tradicionales, serían triviales.
Por ejemplo, hoy vamos a centrarnos en un escenario muy concreto pero frecuente, cuya solución seguro que veis que puede ser aplicada en otros casos: ya que en los records no definimos propiedades de forma explícita, ¿cómo podríamos aplicarles atributos?
Por ejemplo, en el siguiente código definimos un record, creamos una instancia del mismo y mostramos su serialización en JSON por consola:
var p = new Person("John Smith", "jsmith@server.com");
Console.WriteLine(JsonSerializer.Serialize(p));
// Muestra: {"Name":"John Smith","Email":"jsmith@server.com"}
public record Person(string Name, string Email);
Pero imaginad que queremos ignorar la propiedad Email y que la propiedad Name aparezca como fullName. Normalmente usaríamos atributos como [JsonIgnore] o [JsonPropertyName("fullName")] sobre las propiedades para conseguirlo, pero como en este caso no las tenemos disponibles, debemos hacerlo así:
public record Person([property: JsonPropertyName("fullName")] string Name, 
                     [property: JsonIgnore] string Email);
Observad que no se trata de aplicar directamente los atributos [JsonIgnore], porque entonces los estaríamos usando contra los parámetros del constructor del record. Debemos incluir el prefijo property: para indicar que los atributos deben ser aplicados a las propiedades generadas automáticamente a partir de ellos.
De esta forma, si volvemos a ejecutar el código, veremos que ahora la propiedad Email no aparece en la serialización y la propiedad Name aparece como fullName:
var p = new Person("John Smith", "jsmith@server.com");
Console.WriteLine(JsonSerializer.Serialize(p));
// Muestra: {"fullName":"John Smith"}
public record Person([property: JsonPropertyName("fullName")] string Name, 
                     [property: JsonIgnore] string Email);
Como decía más arriba, aunque el ejemplo hayamos visto cómo aplicar atributos de serialización o deserialización, en realidad podríamos hacer lo mismo con cualquier otro tipo de atributo que en condiciones normales aplicaríamos a las propiedades de una clase.
¡Espero que os sea de utilidad! 😊
Publicado en: www.variablenotfound.com.

 
 
 



 
 
 
 
 
 
 
 
 
 
Aún no hay comentarios, ¡sé el primero!
Enviar un nuevo comentario