C # Overriding Igual usando “como” e especializada Método de Correção, Flexibilidade e Desempenho

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

Pergunta

Gostaria de saber sobre a melhor maneira de implementar a correta, flexível e rápido iguais em C #, que pode ser usado para praticamente qualquer classe e situação . Eu percebi que a é igual especializados (tendo um objeto da classe real como parâmetro) é necessária para o desempenho. Para evitar a duplicação de código, os Equals gerais deve chamar o Equals especializados. verificações nulos deve ser realizada apenas uma vez, mesmo em classes herdadas.

Eu finalmente veio com este projeto:


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;
    }
}

idéias importantes:

  • O uso do "como" operador. Desta forma, não temos para verificar se há valores nulos nas Equals gerais. tipos de classes erradas ficar reduzida a um valor nulo e será resolvido nos Equals especializadas.
  • Null cheque em exatamente um ponto, mesmo para as classes derivadas.
  • Verificar o atribui um após o outro fornece uma estrutura clara.

Existem falhas neste conceitos, ou eu perca quaisquer condições?

Foi útil?

Solução

Seu método Equals não é reflexiva quando diferentes tipos estão envolvidos:

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

O caminho normal rodada isso é usar:

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

Veja a documentação em Object.Equals : "x.Equals (y) retorna o mesmo valor como y.equals (x) ". Baseando-se em sobrecarga para dar resultados diferentes pode acabar com horrivelmente questões que seriam muito sutil para depuração.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top