Pergunta

Eu preciso fazer um comparaison entre um objeto e NULL. Quando o objeto não é NULL eu preenchê-lo com alguns dados.

Aqui está o código:

 if (region != null)
 {
  ....
 }

Isso está funcionando, mas quando looping e looping em algum momento o objeto região não é nulo (eu posso ver os dados dentro dele no modo de depuração). No passo-a-passo quando a depuração, ele não ir para dentro da instrução IF ... Quando eu faço um relógio rápido com estes seguinte expressão: eu vejo o (região == null) false retorno, E (região = null ) return false também ... por que e como?

Atualizar

ponto Alguém que o objeto era == e = sobrecarregado:

    public static bool operator ==(Region r1, Region r2)
    {
        if (object.ReferenceEquals(r1, null))
        {
            return false;
        }
        if (object.ReferenceEquals(r2, null))
        {
            return false;
        }

        return (r1.Cmr.CompareTo(r2.Cmr) == 0 && r1.Id == r2.Id);
    }


    public static bool operator !=(Region r1, Region r2)
    {
        if (object.ReferenceEquals(r1, null))
        {
            return false;
        }
        if (object.ReferenceEquals(r2, null))
        {
            return false;
        }
        return (r1.Cmr.CompareTo(r2.Cmr) != 0 || r1.Id != r2.Id);
    }
Foi útil?

Solução

É o == e / ou! = Operador sobrecarregado para a classe do objeto região?

Agora que você já postou o código para as sobrecargas:

As sobrecargas provavelmente deve ter a seguinte aparência (código retirado lançamentos feitos por Jon Skeet e Philip Rieck ):

public static bool operator ==(Region r1, Region r2)
{
    if (object.ReferenceEquals( r1, r2)) {
        // handles if both are null as well as object identity
        return true;
    }

    if ((object)r1 == null || (object)r2 == null)
    {
       return false;
    }        

    return (r1.Cmr.CompareTo(r2.Cmr) == 0 && r1.Id == r2.Id);
}

public static bool operator !=(Region r1, Region r2)
{
    return !(r1 == r2);
}

Outras dicas

Esses sobrecargas de operador estão quebrados.

Em primeiro lugar, torna a vida muito mais fácil se! = É implementado por apenas chamando == e invertendo o resultado.

Em segundo lugar, antes de os controlos de nulidade em == deve haver:

if (object.ReferenceEquals(r1, r2))
{
    return true;
}

Ambos os sobrecargas são incorretos

 public static bool operator ==(Region r1, Region r2)
    {
        if (object.ReferenceEquals(r1, null))
        {
            return false;
        }
        if (object.ReferenceEquals(r2, null))
        {
            return false;
        }

        return (r1.Cmr.CompareTo(r2.Cmr) == 0 && r1.Id == r2.Id);
    }

Se R1 e R2 são nulos, o primeiro teste ( Object.ReferenceEquals (R1, null) ) irá retornar falso, mesmo que r2 é também nulo.

try

//ifs expanded a bit for readability
 public static bool operator ==(Region r1, Region r2)
    {
        if( (object)r1 == null && (object)r2 == null)
        {
           return true;
        }
        if( (object)r1 == null || (object)r2 == null)
        {
           return false;
        }        
        //btw - a quick shortcut here is also object.ReferenceEquals(r1, r2)

        return (r1.Cmr.CompareTo(r2.Cmr) == 0 && r1.Id == r2.Id);
    }

Isto às vezes pode acontecer quando você tem vários segmentos que trabalham com os mesmos dados. Se este for o caso, você pode usar um bloqueio para impedi-los de brincar uns com os outros.

Para comparação de igualdade de um tipo "T", sobrecarregar estes métodos:

int GetHashCode() //Overrides Object.GetHashCode
bool Equals(object other) //Overrides Object.Equals; would correspond to IEquatable, if such an interface existed
bool Equals(T other) //Implements IEquatable<T>; do this for each T you want to compare to
static bool operator ==(T x, T y)
static bool operator !=(T x, T y)

O seu código de comparação de tipo específico deve ser feito em um lugar : a interface IEquatable<T> método Equals(T other) tipo seguro. Se você está comparando a outro tipo (T2), implementar IEquatable<T2> bem, e colocar o código de comparação de campo para esse tipo de Equals (T2 outro).

Todos os métodos sobrecarregados e os operadores devem encaminhar a tarefa de comparação de igualdade com as principais Equals tipo seguro (T outro) método de instância, de tal forma que uma hierarquia de dependência limpa é mantida e garantias mais rigorosas são introduzidas em cada nível para eliminar a redundância e complexidade não essencial .

bool Equals(object other)
{
    if (other is T) //replicate this for each IEquatable<T2>, IEquatable<T3>, etc. you may implement
        return Equals( (T)other) ); //forward to IEquatable<T> implementation
    return false; //other is null or cannot be compared to this instance; therefore it is not equal
}

bool Equals(T other)
{
    if ((object)other == null) //cast to object for reference equality comparison, or use object.ReferenceEquals
        return false;
    //if ((object)other == this) //possible performance boost, ONLY if object instance is frequently compared to itself! otherwise it's just an extra useless check
        //return true;
    return field1.Equals( other.field1 ) &&
           field2.Equals( other.field2 ); //compare type fields to determine equality
}

public static bool operator ==( T x, T y )
{
    if ((object)x != null) //cast to object for reference equality comparison, or use object.ReferenceEquals
        return x.Equals( y ); //forward to type-safe Equals on non-null instance x
    if ((object)y != null)
        return false; //x was null, y is not null
    return true; //both null
}

public static bool operator !=( T x, T y )
{
    if ((object)x != null)
        return !x.Equals( y ); //forward to type-safe Equals on non-null instance x
    if ((object)y != null)
        return true; //x was null, y is not null
    return false; //both null
}

Discussão:

A aplicação anterior centraliza a comparação de tipo específico (isto é, a igualdade de campo) para o final da execução IEquatable<T> para o tipo. Os operadores == e != ter uma implementação paralela mas oposta. Eu prefiro este por ter uma referência a outra, de modo que há uma chamada de método extra para o dependente. Se o operador != é simplesmente vai chamar o operador ==, em vez de oferecer um operador igualmente realizar, então você pode também apenas usar !(obj1 == obj2) e evitar a chamada de método extra. A comparação-se auto é deixado de fora do operador e as implementações IEquatable<T> iguais, porque pode introduzir 1. sobrecarga desnecessária em alguns casos, e / ou 2. desempenho inconsistente dependendo de quantas vezes uma instância é comparado a si vs outras instâncias .

Uma alternativa que eu não gosto, mas deve mencionar, é reverter essa configuração, centralizando o código de igualdade de tipo específico no operador de igualdade vez e ter a Igual métodos dependem disso. Pode-se então utilizar o atalho de ReferenceEquals(obj1,obj2) para verificar se há igualdade de referência e igualdade nula simultaneamente como Philip mencionado em um post anterior, mas essa ideia é enganosa. Parece que você está matando dois pássaros com uma pedra, mas a sua realmente criar mais trabalho - depois de determinar os objetos não são nem tanto nulo nem a mesma instância, então você vai, além disso, ainda tem que para verificar se cada instância é nulo. Na minha aplicação, você verificar para qualquer única instância ser nulo exatamente uma vez. No momento em que o método de instância é chamado Igual, ele já está descartado que o primeiro objeto a ser comparado é nulo, então tudo o que resta a fazer é verificar se o outro é nulo. Então, depois de, no máximo, duas comparações, nós saltar directamente para a verificação de campo, não importa qual o método que usamos (Equals(object),Equals(T),==,!=). Além disso, como já referi, se você realmente está comparando e objeto para si a maior parte do tempo, então você poderia acrescentar que o check-in o método Equals apenas antes de mergulhar nas comparações de campo. O ponto em adicionando-o último é que você ainda pode manter a hierarquia de fluxo / dependência sem a introdução de um redundante / verificação inútil em todos os níveis.

Assim é que estas verificações aqui não está certo:

public static bool operator !=(Region r1, Region r2)
{
    if (object.ReferenceEquals(r1, null))
    {
        return false;
    }
    if (object.ReferenceEquals(r2, null))
    {
        return false;
    }
...

Há uma outra possibilidade de que você precisa clicar no ícone de atualização ao lado do parâmetro que você está assistindo. VS tentar manter-se com o desempenho enquanto não avaliar cada declaração / parâmetro. Dê uma olhada para se certificar, antes de começar a fazer mudanças para lugares que Non relevante.

bool comp;
if (object.IsNullOrEmpty(r1))
{
    comp = false;
}

if (object.IsNullOrEmpty(r2))
{
    comp = false;
}
return comp;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top