miércoles, 27 de julio de 2016

Comparación de Igualdad en C# | Parte 3/5 | Protocolos de Igualdad Estándar: Método static object.ReferenceEquals e Interfaz IEquatable

Índice

1. Introducción
2. Palabras Clave
3. Método static object.ReferenceEquals
4. Interfaz IEquatable<T>
5. Cuándo Equals no es equivalente a ==
6. Conclusiones
7. Literatura & Enlaces

1. Introducción

Esta tercera parte de la serie Comparación de Igualdad en C# describe el método static object.ReferenceEquals y la interfaz IEquatable<T> como protocolos de igualdad estándar. Particularmente se describe cómo el programador puede realizar únicamente la comparación por referencia, y la personalización del método Equals como mecanismo de alto rendimiento frente a la técnica de boxing.

2. Palabras Clave

  • Boxing
  • Comparación
  • Igualdad
  • Interfaz IEquatable<T>
  • object.ReferenceEquals

3. Método static object.ReferenceEquals

A través del método static object.ReferenceEquals(Object, Object) se determina si dos instancias object corresponden con la misma instancia ("Object.ReferenceEquals Method", 2016).

Esta su sintaxis: 

public static bool ReferenceEquals(
object objA,
object objB);

Ejemplo de uso (LINQPad)

De acuerdo con Albahari (2012), este método de comparación de referencias resulta útil en situaciones tales como: 
  • La clase Editor ha sobrescrito el método virtual Equals de tal modo que la expresión e1.Equals(e2)retorna True.
  • La clase Editor ha sobrecargado el operador ==, y éste en la expresión e1 == e2 también retorna true.
Por lo tanto invocar a object.ReferenceEquals garantiza el comportamiento de comparación de igualdad por referencias.

4. Interfaz IEquatable<T>

Un coste grande asociado a la invocación del método static está relacionado con la alta demanda computacional de la operación de envoltura (boxing; cfrBoxing y Unboxing en C#). Esta operación no resulta apropiada para escenarios de alto rendimiento.

Con respecto a lo anterior, a partir de la versión 2.0 de C# se introdujo la interfaz IEquatable<T>. Esta interfaz define el método Equals que tanto un tipo de dato por valor o como uno por referencia pueden implementar para la determinación de igualdad de instancias ("IEquatable<T> Interface", 2016).

public interface IEquatable<T>
{
bool Equals(T other);
}

¿Cuál es su propósito? Una vez implementado el método Equals de esta interfaz, la idea es obtener el mismo resultado del método virtual Equals, pero más rápido (Albahari, 2012).

Ejemplo de uso (LINQPad): 

En caso que se remueva la restricción del genérico, la comparación a.Equals(b) se realiza con la versión lenta object.Equals (Albahari, 2012).

5. Cuándo Equals no es equivalente a ==

En determinados escenarios el comportamiento de equivalencia del método virtual Equals no es igual al operador ==. En un contexto matemático el siguiente ejemplo es un caso evidente: 

double x = double.NaN;
Console.WriteLine(x == x); // False
Console.WriteLine(x.Equals(x)); // True

La sobrescritura del operador == sobre variables de tipo double define que el miembro NaN no es igual a NaN. Esto tiene tanto el sentido matemático como en el comportamiento inherente de la unidad de procesamiento central (CPU) (Albahari, 2012).

Por otro lado, la clase StringBuilder constituye otro ejemplo de tipo de dato que implementa un comportamiento divergente entre el operador == y el método Equals.

Ejemplo de uso

var sb1 = new StringBuilder("Universidad de los Andes (Colombia)");
var sb2 = new StringBuilder("Universidad de los Andes (Colombia)");
Console.WriteLine(sb1 == sb2); // False: Igualdad por referencia
Console.WriteLine(sb1.Equals(sb2)); // True: Igualad por valor

6. Conclusiones

Se estudiaron otros de los elementos de programa que conforman los protocolos de igualdad estándar: object.ReferenceEquals, la interfaz IEquatable<T>. El conocimiento de éstos facilita al programador crear una semántica de igualdad entre instancias de tipos de datos acorde al contexto que se esté modelando.

La siguiente parte estará enfocada en el estudio de la igualdad en tipos personalizados.

7. Literatura & Enlaces

Albahari, J., Albahari, B. (2012). C# 5.0 in a Nutshell. United States: O'Reilly Media.
Comparación de Igualdad en C# | Parte 2/5 | Protocolos de Igualdad Estándar: ==, != y virtual Object.Equals y static object.Equals (2016, julio 26). Recuperado desde: https://ortizol.blogspot.com/2016/07/comparacion-de-igualdad-en-csharp-parte-2-4-protocolos-de-igualdad-estandar-igual-igual-difernte-de-y-virtual-object.equals-y-static-object.equals.html
Boxing y Unboxing en C# (2016, julio 26). Recuperado desde: https://ortizol.blogspot.com.co/2014/03/boxing-y-unboxing-en-c.html
IEquatable(T) Interface (System) (2016, julio 26). Recuperado desde: https://msdn.microsoft.com/en-us/library/ms131187(v=vs.110).aspx


O

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.