valor tipos textuales referencias referencia qué por pasar parametros objetos método ejemplos comparar como clases c# .net

textuales - C#compara dos objetos de tipos desconocidos(incluidos los tipos de referencia y de valor)



tipos de referencias textuales (5)

¿Es posible en C # comparar dos objetos de tipos desconocidos (incluidos los tipos de referencia y de valor) utilizando sus comparadores de tipo si existen?

El objetivo es escribir una función que tenga una firma como esta:

public bool Compare(object a, object b) { // compare logic goes here }

Cuál regresaría

Compare(100d, 100d) == true Compare(100f, 100f) == true Compare("hello", "hello") == true Compare(null, null) == true Compare(100d, 101d) == false Compare(100f, null) == false // Use type comparators where possible, i.e.: Compare(new DateTime(2010, 12, 01), new DateTime(2010, 12, 01)) == true Compare(new DateTime(2010, 12, 01), new DateTime(2010, 12, 02)) == false Compare(new DateTime(2010, 12, 01), null) == false

¿Existe un enfoque genérico para resolver este problema que funcionaría para cualquier tipo de objeto?


¿Qué tal object.equals(x, y) ? Esto también aceptará valores nulos.


No estoy 100% seguro de si esto funciona en todos los casos, pero pruébalo

public bool Compare(object a, object b) { return a.Equals(b); }


Puede usar el object.Equals(object x, object y) static object.Equals(object x, object y) y no molestar en escribir su método. Eso manejará nulos apropiadamente, y delegará a una implementación de object.Equals(object) asociado con x o y ... no debería importar cuál, ya que Equals debe ser simétrico.

Tenga en cuenta que esto no utiliza los operadores == para ningún tipo: los operadores no pueden anularse, solo sobrecargarse (lo que significa que se eligen en tiempo de compilación , no en tiempo de ejecución . En la mayoría de los casos, Equals debe hacer lo que usted desee En algunos casos, == puede no estar sobrecargado aunque Equals esté anulado ... pero nunca he sabido que el reverso sea verdadero en ninguno de los tipos con los que he trabajado.

Tenga en cuenta que el uso de este enfoque encajonará cualquier tipo de valor ...

EDITAR: sección eliminada sobre la reimplementación efectiva, mal, EqualityComparer<T>.Default . Vea la respuesta de Marc para más. Esto no te ayudará si no puedes usar un tipo genérico, por supuesto.

Un último punto: no llamaría a su método Compare . Ese nombre generalmente se asocia con ordenar valores en lugar de compararlos para la igualdad.


Qué pasa

if (a == null && b == null) return true; if (a == null && b != null) return false; return (a.equals(b));

?


Una opción razonable es trabajar con genéricos, es decir,

public bool Compare<T>(T a, T b) {...}

No necesitará especificar la T en su código, ya que el compilador generalmente podrá resolverlo (es decir, sus muestras existentes funcionarían "tal cual")

Para la implementación:

bool equal = EqualityComparer<T>.Default.Equals(x, y);

(para el tipo genérico T )

pero en realidad evitaría la palabra Compare , ya que se usa en otro lugar para significar < / == / > - así que podría tener:

public static bool Equals<T>(T a, T b) { return EqualityComparer<T>.Default.Equals(a, b); }

Esta:

  • evita el boxeo cuando T es una estructura
  • maneja nulos / Nullable<T> correctamente
  • admite IEquatable<T>
  • o regresa a Equals regulares

no utiliza el operador == , pero MiscUtil tiene una clase de Operator que lo hará , a través de

bool equal = Operator.Equal<T>(x,y);

(tenga en cuenta que este último fallará si T no tiene un operador == , aunque pensando en ello, podría utilizar EqualityComparer<T>.Default.Equals como una alternativa, simplemente no lo hace)

Para completar, tenga en cuenta que Comparer<T>.Default.Compare(x,y) maneja las operaciones de comparación.