Pregunta

Tengo algunos tipos genéricos, como la siguiente:

public struct Tuple<T1, T2> { ... }
public struct Tuple<T1, T2, T3> { ... }
etc.

Estos deberían, en teoría, ser capaz de compararse con otros valores del mismo tipo, de modo que pueda escribir el siguiente tipo de código:

List<Tuple<Type, String>> l = new List<Tuple<Type, String>>();
l.Add(new Tuple<Type, String>(typeof(ISomeInterface), "123"));
if (l.Contains(new Tuple<Type, String>(typeof(ISomeOtherInterface), "123"))
    ...

Por desgracia, había un error en mi código, y la pregunta es cómo hacer esto correctamente.

El error tuvo que ver con mi aplicación de CompareTo>, que básicamente es el siguiente:

Int32 result = HelperMethods.CompareTwoFields<T1>(_Value1, other._Value1);
if (result != 0)
    return result;

Int32 result = HelperMethods.CompareTwoFields<T2>(_Value2, other._Value2);
if (result != 0)
    return result;

return 0;

HelperMethods.CompareTwoFields se parece a esto:

internal static Int32 CompareTwoFields<T>(T field1, T field2)
{
    Int32 result = 0;
    if (ReferenceEquals(field1, null) != ReferenceEquals(field2, null))
        result = ReferenceEquals(field1, null) ? -1 : +1;
    else if (!ReferenceEquals(field1, null) && field1 is IComparable<T>)
        result = ((IComparable<T>)field1).CompareTo(field2);
    else if (!typeof(T).IsValueType)
    {
        if (Object.ReferenceEquals(field1, field2))
            return 0;
        else
            return field1.ToString().CompareTo(field2.ToString());
    }
    return result;
}

La última sentencia if hay algo que me metí ahora reparar el fallo, pero ¿es esto correcto?

Básicamente, ¿cómo comparar dos objetos de tipo? ¿Hay una comparación significativa de éstos, excepto sólo para convertirlos en una cadena y comparar?

¿Fue útil?

Solución

¿Se refiere a:

bool equal = EqualityComparer<T>.Default.Equals(val1,val2);

Esto funciona con IEquatable<T> (por T : IEquatable<T>), de lo contrario se cae de nuevo a object.Equals.

También hay Comparer<T>.Default para las comparaciones de desigualdad (más / menos):

int delta = Comparer<T>.Default.Compare(val1,val2);

Esto utiliza T : IComparable<T>, o T : IComparable lo contrario.

Por cierto, Type sólo debe utilizar la referencia habitual comparar proporcionada por <=>, por lo que sólo debería funcionar bien con lo anterior.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top