Anulación de C # es igual usando & # 8220; como & # 8221; y método especializado para la corrección, flexibilidad y rendimiento

StackOverflow https://stackoverflow.com/questions/460846

Pregunta

Me preguntaba cuál era la mejor manera de implementar un Equal correcto, flexible y rápido en C #, que se pueda utilizar para prácticamente cualquier clase y situación . Pensé que se necesita un Igual especializado (tomando un objeto de la clase real como parámetro) para el rendimiento. Para evitar la duplicación de código, los Iguales generales deben llamar a los Iguales especializados. Las comprobaciones nulas deben realizarse solo una vez, incluso en clases heredadas.

Finalmente se me ocurrió este diseño:


class MyClass
{
    public Int32 SomeValue1 = 1;
    public Int32 SomeValue2 = 25;

    // Ignoring GetHashCode for simplicity.

    public override bool Equals(object obj)
    {
        return Equals (obj as MyClass);
    }

    public bool Equals(MyClass obj)
    {
        if (obj == null) {
            return false;
        }

        if (!SomeValue1.Equals (obj.SomeValue1)) {
            return false;
        }

        if (!SomeValue2.Equals (obj.SomeValue2)) {
            return false;
        }

        return true;
    }
}

class MyDerivedClass : MyClass
{
    public Int32 YetAnotherValue = 2;

    public override bool Equals(object obj)
    {
        return Equals (obj as MyDerivedClass);
    }

    public bool Equals(MyDerivedClass obj)
    {
        if (!base.Equals (obj)) {
            return false;
        }

        if (!YetAnotherValue.Equals (obj.YetAnotherValue)) {
            return false;
        }

        return true;
    }
}

Ideas importantes:

  • Uso de " como " operador. De esta manera, no tenemos que verificar nulos en los iguales generales. Los tipos de clase incorrectos se reducen a nulos y se resolverán en los Iguales especializados.
  • Verificación nula exactamente en un punto, incluso para clases derivadas.
  • Verificar los atributos uno tras otro proporciona una estructura clara.

¿Hay fallas en estos conceptos, o se me pasó alguna condición?

¿Fue útil?

Solución

Su método Equals no es reflexivo cuando hay diferentes tipos involucrados:

MyDerivedClass mdc = new MyDerivedClass();
MyClass mc = new MyClass();
Object omdc = mdc;
Object omc = mc;

// mc.Equals(mdc) - true
// mdc.Equals(mc) - true by calling the right overload
// omc.Equals(omdc) - true
// omdc.Equals(omc) - false, the "as" in MyDerivedClass will result in null

La forma normal de evitar esto es usar:

if (GetType() != other.GetType())
{
    return false;
}

Vea los documentos en Object.Equals : " x. Igual (y) devuelve el mismo valor que y. Igual (x). & Quot; Confiar en la sobrecarga para obtener resultados diferentes podría terminar con problemas horriblemente que serían muy sutiles para depurar.

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