En el lenguaje de programación C#, un objeto puede ser un tipo de valor o un tipo de referencia. Si bien un objeto es un objeto, la diferencia entre tipos de valor y tipos de referencia se reduce a la naturaleza de sus variables. Una variable de un tipo de valor contiene un objeto o una instancia del tipo. Una variable de un tipo de referencia contiene una referencia a un objeto o una referencia a una instancia del tipo.
C# también nos permite crear lo que se llama objetos de valor, un tipo especial de objeto utilizado en el diseño basado en dominios que nos permite articular conceptos de dominio de manera simple, clara y concisa. En este artículo examinaremos los objetos de valor, discutiremos sus beneficios e ilustraremos cómo podemos usarlos en C#.
Crear un proyecto de aplicación de consola en Visual Studio
En primer lugar, creemos un proyecto de aplicación de consola .NET Core en Visual Studio. Suponiendo que Visual Studio 2022 esté instalado en su sistema, siga los pasos que se describen a continuación para crear un nuevo proyecto de aplicación de consola central .NET.
- Inicie el IDE de Visual Studio.
- Haga clic en «Crear nuevo proyecto».
- En la ventana «Crear nuevo proyecto», seleccione «Aplicación de consola (.NET Core)» de la lista de plantillas que se muestran.
- Haga clic en Siguiente.
- En la ventana «Configura tu nuevo proyecto», especifica el nombre y la ubicación del nuevo proyecto.
- Haga clic en Siguiente.
- En la ventana «Información adicional», elija «.NET 8.0 (soporte a largo plazo)» como la versión del marco que desea utilizar.
- Deje sin marcar las casillas de verificación «No utilizar declaraciones de nivel superior» y «Habilitar publicación AOT nativa».
- Haga clic en Crear.
Usaremos este proyecto de aplicación de consola .NET 8 para trabajar con objetos de valor en las secciones siguientes de este artículo.
¿Qué son los objetos de valor en C#?
En el lenguaje C#, un objeto de valor se define como un objeto que sólo puede identificarse por el estado de sus propiedades. Los objetos de valor representan un aspecto descriptivo de un dominio sin tener una identidad. En otras palabras, los objetos de valor representan elementos del diseño que nos importan sólo en términos de su contenido, no de su identidad.
En el diseño impulsado por dominio (DDD), el patrón de objeto de valor representa objetos sin identidad y admite la igualdad en función de sus atributos. Cabe señalar aquí que, a diferencia de los objetos de valor, los objetos de entidad tienen identidades distintas. A diferencia de los objetos de entidad, que se definen por su identidad y tienen un estado mutable, los objetos de valor se definen por sus atributos y son inmutables.
La inmutabilidad significa que no se puede cambiar un objeto de valor una vez que se ha creado; cualquier operación realizada en objetos de valor creará una nueva instancia. La inmutabilidad de los objetos de valor tiene importantes beneficios de rendimiento. Debido a que dos objetos de valor se consideran iguales si contienen valores idénticos, incluso si pueden ser objetos diferentes, se vuelven intercambiables. En otras palabras, la inmutabilidad permite la reutilización de objetos.
Un ejemplo de objetos de valor en C#
Considere la siguiente clase denominada Dirección, que contiene algunas propiedades y un constructor de argumentos.
public class Address { public string HouseNo { get; set; } public string Street { get; set; } public string ZipCode { get; set; } public string City { get; set; } public Address(string houseno, string street, string zipCode, string city) { HouseNo = houseno; Street = street; ZipCode = zipCode; City = city; } }
Puede crear una instancia de esta clase y asignar valores a sus propiedades usando el siguiente código.
Address address = new Address("505", "Woodland Street", "CR2 8EN", "London");
Sin embargo, debido a que la clase Address aquí expone configuradores públicos, podría cambiar fácilmente los valores de sus propiedades desde fuera de la clase. Esto viola una de las características básicas de los objetos de valor, es decir, su soporte a la inmutabilidad.
Podemos solucionar este problema rediseñando la clase Dirección como se muestra a continuación.
public class Address { public string HouseNo { get; private set; } public string Street { get; private set; } public string ZipCode { get; private set; } public string City { get; private set; } public Address(string houseno, string street, string zipCode, string city) { HouseNo = houseno; Street = street; ZipCode = zipCode; City = city; } }
Como puede ver arriba, las propiedades de nuestra nueva clase Dirección contienen configuradores privados, que no permiten cambios en el valor de ninguna de estas propiedades desde fuera de la clase, preservando así la inmutabilidad. Si ejecuta este programa, aparecerá el error que se muestra en la Figura 1 a continuación.
También puede implementar objetos de valor utilizando registros en C#. Para hacer esto, use la palabra clave record para definir un tipo de registro que encapsule datos de la misma manera que lo hicimos anteriormente con la clase Autor. El siguiente fragmento de código muestra cómo se puede definir un tipo de registro en C#.
public record Address(string Houseno, string Street, string ZipCode, string City);
Mejores prácticas para usar objetos de valor en C#
Cuando trabaje con objetos de valor en C#, debe seguir estas prácticas recomendadas:
- Implemente controles de igualdad adecuados basados en el valor para evitar inconsistencias y errores.
- Utilice objetos de valor para representar conceptos en el modelo de dominio sólo cuando lo considere apropiado.
- Utilice los objetos de valor con prudencia porque tienen gastos generales de rendimiento.
- Considere implementar una lógica de validación dentro de su constructor de objetos de valor para hacer cumplir las reglas y restricciones comerciales cuando se crea el objeto de valor.
- Siga los patrones recomendados y las convenciones de nomenclatura para garantizar claridad, coherencia y legibilidad en las implementaciones de sus objetos de valor.
Los objetos de valor encapsulan tipos primitivos y tienen dos propiedades principales, es decir, no tienen identidad y son inmutables. Los objetos de valor pueden simplificar estructuras de datos complejas al encapsular datos relacionados en una sola unidad. Esto garantiza la integridad de los datos, impone una escritura segura, reduce los errores y mejora la legibilidad del código fuente. Puede aprovechar los objetos de valor para mejorar la claridad y la capacidad de mantenimiento de su código C# al proporcionar una representación más expresiva de los conceptos del dominio.
Normalmente, la creación de objetos de valor en C# implica anular la comparación de igualdad e implementar una semántica adecuada basada en valores. Una práctica típica implica anular los métodos Equals() y GetHashCode() y proporcionar otros operadores para comparar. Normalmente, utilizamos una clase base que comprende estos métodos que todas las implementaciones de objetos de valor deberían ampliar.
En el ejemplo anterior, proporcioné una implementación básica de objetos de valor en C#. En una publicación futura aquí, exploraré cómo podemos implementar una clase base de objeto de valor y discutiré conceptos más avanzados.
Copyright © 2024 IDG Communications, Inc.