Índice
1. Introducción2. Palabras Clave
3. Comparación de Igualdad
3.1 Generalidades
3.2 Igualdad por valor vs. igualdad por referencia
3.2.1 Iguadad por valor
3.2.1 Igualdad por referencia
4. Conclusiones
5. Literatura & Enlaces
1. Introducción
Un tema que adquiere un grado atención relevante en .NET Framework tiene que ver con la comparación de igualdad de elementos de datos ya sea de tipos por valor o tipos por referencia. Se inicia esta serie de artículos C# para el estudio y comprensión de los escenarios particulares de uso de comparación integrada y la propia creada por el programador.
Esta serie se divide en 5 partes:
- Tipos de Igualdad
- Protocolos de Igualdad Estándar: ==, != y virtual Object.Equals, static object.Equals
- Protocolos de Igualdad Estándar: método static object.ReferenceEquals e interfaz IEquatable<T>
- Personalización de los Tipos de Igualdad - Generales
- Personalización de los Tipos de Igualdad - Sobrecarga y Sobrescritura
Uno de los propósitos de esta serie es dejar claro al programador que la comparación de igualdad requiere invertir esfuerzos considerables para entender sus complejidades y sutilezas inherentes.
En esta primera se describe las categorías o tipos de igualdad en C#. Para esto se estudia la igualdad por valor y valor por referencia. Estas dos formas operativas de igualdad actúan teniendo en cuenta el contexto implementación, tipos integrados y personalizados.
2. Palabras Clave
- .NET
- C#
- Comparación
- Contexto de implementación
- Igualdad
- Tipo integrado
- Tipo personalizado
3. Comparación de Igualdad
3.1 Generalidades
En este punto al programador le ha quedado claro el uso de los operadores de igualdad: == y !=. Esto a nivel fundamental; sin embargo, hay que apuntar que el uso de estos operadores de igualdad en otros escenarios conlleva a implementar requerimientos más complejos para efectuar la comparación de equivalencia entre objetos y valores (Albahari, 2012). En la Figura 1 se ilustra 4 ambientes que implican el incremento de dificultad en esta operación:
Figura 1. Vectores de dificultad comparación de igualdad ("C# Equality and Comparisons", 2016). |
Ejemplos de uso:
1. Igualdad por valor o referencia
Console.WriteLine(3 == 3);
Console.WriteLine((object)3 == (object)3);
La primera expresión genera como resultado True, mientras que la segunda False. Esto último se debe a que la comparación de igualdad se efectúa a nivel de referencia: los valores enteros 3 son encajados/envueltos (boxed) en diferentes instancias object.
2. Múltiples mecanismos de comparación de valores
Console.WriteLine("Uniandes" == "Uniandes");
Console.WriteLine("Uniandes" == "uniandes");
El programador sabrá que la primera expresión es True y la segunda False. La razón reside en que la decisión de diseño nativa de comparación de valores de cadenas es a nivel de carácter, es decir de valor y no por referencia; a pesar de que string sea un tipo de dato por referencia.
3. Exactitud
float x = 6.0000001f;
float y = 6.0000000f;
Console.WriteLine(x == y);
¿False o True?...
Aunque parezca extraño el resultado de esta expresión de comparación de igualdad es True. ¿La razón? La representación de valores de punto flotante en la memoria no es exacta como podemos pensar.
En cuanto a
Console.WriteLine(x < y);
el valor resultante es False. Por lo tanto no se recomiendo usar el comparador de igualdad para valores de punto flotante.
4. Conflicto con POO
El último caso tiene que ver con el conflicto que se genera con la propiedad polimórfica de manipulación de objetos en una jerarquía de herencia.
Nótese que cada implementación de Equals recibe como argumento un objeto de clase distinta: Comida y ComidaCocinada.
3.2 Igualdad por valor vs. igualdad por referencia
En Microsoft .NET Framework existen tipos de igualdad (Albahari, 2012):
- Igualdad por valor: Dos valores son equivalentes de acuerdo a una semántica particular.
- Igualdad por referencia: Dos referencias apuntan al mismo objeto en memoria.
Los tipos por valor usan el primero tipo de igualdad -igualdad por valor-, y los tipos por referencia igualdad por referencia.
3.2.1 Igualdad por valor
Como ya se mencionó, los tipos por valor usan la igualdad por valor. La comparación por igualdad funciona mientras que un valor numérico no sea encajado/envuelto en object.
int x = 7;
int y = 7;
Console.WriteLine(x == y);
Este ejemplo ilustra la igualdad por referencia, que por virtud es igual a True.
Otro tipo de estructuras, como DateTime, usan el operador de igualdad == para comparar los valores de diferentes intancias:
var dt1 = new DateTime(2012, 1, 1, 12, 1, 1);
var dt2 = new DateTime(2012, 1, 1, 12, 1, 1);
Console.WriteLine(dt1 == dt2);
Console.WriteLine(dt1 == dt2);
El resultado es True.
3.2.2 Igualdad por referencia
Los tipos de datos por referencia recurren a la igualdad por referencia de forma predeterminada.
El siguiente ejemplo demuestra el funcionamiento del operador de igualdad == con dos objetos de un tipo de dato personalizado.
Una vez ejecutado este fragmento de código en LINQPad, este es el resultado obtenido:
False
Aquí no se compara los valores del campo X sino las referencias de los objetos instanciados.
Sin embargo, cuando el programador realiza una comparación como la siguiente
var cp3 = cp2;
Console.WriteLine(cp2 == cp3);
el resultado es True. Esto es así porque tanto cp1 y cp2 se refieren al mismo objeto en memoria.
4. Conclusiones
Se introdujeron los conceptos fundamentales acerca de la comparación de igualdad en C#. Tener claros estos conceptos facilita la creación de tipos de datos personalizados que requieren implementar un mecanismo de comparación de igualdad basado en una semántica particular.
La siguiente parte de esta serie expondrá los protocolos de igualdad estándar.
5. Literatura & Enlaces
Albahari, J., Albahari, B. (2012). C# 5.0 in a Nutshell. United States: O'Reilly Media.C# Equality and Comparisons (2016, julio 25). Recuperado desde: https://app.pluralsight.com/library/courses/csharp-equality-comparisons
O
No hay comentarios:
Publicar un comentario
Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.