Pergunta

Eu tenho uma condição em um aplicativo do Silverlight que compara 2 cordas, por algum motivo, quando eu uso == ele retorna false enquanto .Equals() retornos true .

Aqui está o código:

if (((ListBoxItem)lstBaseMenu.SelectedItem).Content.Equals("Energy Attack"))
{
    // Execute code
}

if (((ListBoxItem)lstBaseMenu.SelectedItem).Content == "Energy Attack")
{
    // Execute code
}

Você tem algum motivo por que isso está acontecendo?

Foi útil?

Solução

Quando == é usado em uma expressão do tipo object, vai resolver a System.Object.ReferenceEquals .

Equals é apenas um método virtual e se comporta como tal, de modo a versão substituída serão utilizados (o que, para o tipo string compara o conteúdo).

Outras dicas

Ao comparar um objecto de referência para uma cadeia (até mesmo se o objecto de referência refere-se a uma cadeia de caracteres), a comportamentos especiais do operador == específico para a classe de cadeia é ignorado.

Normalmente (quando não estiver lidando com cordas, que é), Equals compara valores , enquanto == compara objeto referências . Se dois objetos que você está comparando são referindo-se à mesma instância exata de um objeto, em seguida, ambos vão retornar verdadeiro, mas se alguém tem o mesmo conteúdo e veio de uma fonte diferente (é uma instância separada com os mesmos dados), apenas é igual a vontade return true. No entanto, como observado nos comentários, corda é um caso especial porque ele substitui o operador == de modo que quando se trata puramente com referências de cordas (e não referências de objeto), apenas os valores são comparados mesmo se eles são instâncias separadas. O código a seguir ilustra as sutis diferenças em comportamentos:

string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3;
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s2), s1 == s2, s1.Equals(s2));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s3), s1 == s3, s1.Equals(s3));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s4), s1 == s4, s1.Equals(s4));

A saída é:

True True True
False True True
False False True

== e .Equals são ambos dependentes do comportamento definido no tipo real e o tipo real no site da chamada. Ambos são apenas métodos / operadores que podem ser substituídas em qualquer tipo e dado qualquer comportamento o autor assim o desejar. Na minha experiência, eu acho que é comum as pessoas para implementar .Equals em um objeto, mas negligenciam a implementar == operador. Isto significa que .Equals irá realmente medir a igualdade dos valores enquanto == vai medir se eles são ou não a mesma referência.

Quando estou trabalhando com um novo tipo cuja definição está em fluxo ou escrevendo algoritmos genéricos, acho que a melhor prática é o seguinte

  • Se eu quiser comparar referências em C #, eu uso Object.ReferenceEquals diretamente (não é necessário no caso genérico)
  • Se eu quiser comparar valores eu uso EqualityComparer<T>.Default

Em alguns casos, quando eu sinto o uso de == é ambígua vou usar explicitamente Object.Reference igual no código para remover a ambigüidade.

Eric Lippert fez recentemente um post sobre o assunto de por que existem 2 métodos de igualdade no CLR. Vale a pena ler

Em primeiro lugar, há é a diferença. Para números

> 2 == 2.0
True

> 2.Equals(2.0)
False

E para cordas

> string x = null;
> x == null
True

> x.Equals(null)
NullReferenceException

Em ambos os casos, comporta == mais útil do que .Equals

Gostaria de acrescentar que, se você lançar o seu objeto para uma string, então ele vai funcionar corretamente. É por isso que o compilador vai lhe dar um aviso dizendo:

comparação de referência não intencional possível; para obter uma comparação de valor, lançado do lado esquerdo para o tipo 'string'

== Operador 1. Se os operandos são Valor Tipos e seus valores são iguais, ele retorna verdadeiro falso mais. 2. Se os operandos são com exceção de corda e ambos se referem a mesmo objeto, ele retorna verdadeiro falso mais. 3. Se os operandos são do tipo string e seus valores são iguais, ele retorna verdadeiro falso outra pessoa.

.Equals 1. Se operandos são tipos de referência, ele executa Referência Igualdade isto é, se ambos se referem ao mesmo objeto, ele retorna verdadeiro falso mais. 2. Se Operandos são tipos de valor, em seguida, ao contrário == operador verifica a existência de seu tipo em primeiro lugar e se os seus tipos são mesmo ele executa == operador senão ele retorna falso.

Tanto quanto eu entendo que a resposta é simples:

  1. == compara referências de objeto.
  2. .Equals compara conteúdo do objeto.
  3. string tipos de dados sempre agir como comparação conteúdo.

Espero que eu esteja correto e que ele respondeu a sua pergunta.

Como a versão estática do método .Equal não foi mencionado até agora, eu gostaria de adicionar esta aqui para resumir e comparar os 3 variações.

MyString.Equals("Somestring"))          //Method 1
MyString == "Somestring"                //Method 2
String.Equals("Somestring", MyString);  //Method 3 (static String.Equals method) - better

onde MyString é uma variável que vem de algum outro lugar no código.

info fundo e summerize:

Em Java usando == para comparar strings não deve ser usado. Digo isto no caso de você precisar usar ambas as línguas e também para que você saiba que o uso == também pode ser substituído por algo melhor em C #.

Em C # não há nenhuma diferença prática para cordas comparando utilizando o Método 1 ou 2, desde que ambos são do tipo string. No entanto, se um é nulo, uma é de outro tipo (como um inteiro), ou um representa um objeto que tem uma referência diferente, então, como a questão mostra iniciais, pode ocorrer que, comparando o conteúdo para a igualdade não pode retornar o você espera.

Solução sugerida:

Como o uso == não é exatamente o mesmo que usar .Equals quando comparando as coisas, você pode usar String.Equals estáticos método em vez. Dessa forma, se os dois lados não são do mesmo tipo que você ainda irá comparar o conteúdo e se é nulo, você vai evitar a exceção.

   bool areEqual = String.Equals("Somestring", MyString);  

É um pouco mais para escrever, mas na minha opinião, mais seguro de usar.

Eis aqui algumas informações copiadas de Microsoft:

public static bool Equals (string a, string b);

Parâmetros

Cordas a

A primeira cadeia de comparar, ou null.

Cordas b

A segunda corda para comparar, ou null.

Retorna Boolean

true se o valor do a é o mesmo que o valor de b; caso contrário, false. Se ambos a e b são null, o método retorna true.

Estou um pouco confuso aqui. Se o tipo de tempo de execução de conteúdo é do tipo string, então ambos == e Equals deve retornar true. No entanto, uma vez que este não parece ser o caso, tipo, em seguida, tempo de execução do conteúdo não é corda e Equals, convidando-o está fazendo uma igualdade referencial e isso explica por que Equals ( "Ataque de Energia") falhar. No entanto, no segundo caso, a decisão sobre qual sobrecarregado == operador estática deve ser chamado é feito em tempo de compilação e esta decisão parece ser == (string, string). Isto sugere-me que o Conteúdo fornece uma conversão implícita para string.

Há uma outra dimensão para uma resposta mais cedo por @BlueMonkMN. A dimensão adicional é que a resposta para a pergunta do título @ de Drahcir como se afirma também depende de como chegamos ao valor string. Para ilustrar:

string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3;
string s5 = "te" + "st";
object s6 = s5;
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s2), s1 == s2, s1.Equals(s2));

Console.WriteLine("\n  Case1 - A method changes the value:");
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s3), s1 == s3, s1.Equals(s3));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s4), s1 == s4, s1.Equals(s4));

Console.WriteLine("\n  Case2 - Having only literals allows to arrive at a literal:");
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s5), s1 == s5, s1.Equals(s5));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s6), s1 == s6, s1.Equals(s6));

A saída é:

True True True

  Case1 - A method changes the value:
False True True
False False True

  Case2 - Having only literals allows to arrive at a literal:
True True True
True True True

Como adicionar mais um ponto para a resposta.

método .EqualsTo() lhe dá provisão para comparar com a cultura e maiúsculas e minúsculas.

Assim como um complemento para as já boas respostas: Este comportamento não é limitado a Strings ou comparar diferentes numbertypes. Mesmo que ambos os elementos são do tipo de objecto do mesmo tipo subjacente. "==" não vai funcionar.

A figura abaixo mostra os resultados da comparação de dois objecto {int} - valores

Exemplo de VS2017

O == sinal em C # é usado para dois operadores igualdade-de seleção diferentes. Quando os encontros compilador que modo, ele vai verificar se qualquer um dos tipos sendo comparados implementou uma sobrecarga igualdade-operador para ambos os tipos de combinação específicos a serem comparadas (*), ou por uma combinação de tipos de que os dois tipos podem ser convertidos. Se o compilador encontra uma sobrecarga tal, vai usá-lo. Caso contrário, se os dois tipos são ambos os tipos de referência e não são classes independentes (ou pode ser uma interface, ou eles podem ser classes relacionadas), o compilador considerará == como um operador de referência-comparação. Se nenhuma condição aplica-se, a compilação irá falhar.

Note que alguns outros idiomas utilizam fichas separadas para os dois operadores de igualdade-seleção. Em VB.NET, por exemplo, o símbolo = é usado dentro das expressões exclusivamente para o operador de igualdade de verificação sobrecarregável, e Is é usado como uma referência-teste ou operador de nulo-teste. Um usar = em um tipo que não se sobrepõe à igualdade de verificação operador irá falhar, como a vontade de tentar usar Is para qualquer outra finalidade que não testar igualdade de referência ou nulidade.

(*) Tipos geralmente só sobrecarregar igualdade para comparação com eles mesmos, mas pode ser útil para tipos de sobrecarregar o operador de igualdade para comparação com outros tipos particulares; por exemplo, int poderia ter (e IMHO deve ter, mas não o fez) definiu uma operadores de igualdade para comparação com float, de modo que 16777217 não iria denunciar-se igual a 16777216f. Como é, desde há tal operador é definido, C # irá promover a int para float, arredondando-o para 16777216f antes do operador de igualdade-check vê-lo; esse operador, em seguida, vê dois números de ponto flutuante de igualdade e relatórios-los como iguais, sem saber do arredondamento que ocorreu.

realmente grandes respostas e exemplos!

Eu gostaria apenas de acrescentar a diferença fundamental entre os dois,

Operadores como == não são polimórficos, enquanto Equals é

Com esse conceito em mente, se você trabalha fora qualquer exemplo (por olhando para a mão esquerda e tipo de referência mão direita, e verificando / saber se o tipo de verdade tem == operador sobrecarregado e é igual a ser anulado) que você está certo para obter a resposta certa.

Quando criamos qualquer objeto existem duas partes para o objeto é o conteúdo e o outro é referência a esse conteúdo. == compara o conteúdo e de referência; equals() compara apenas conteúdo

http: // www. codeproject.com/Articles/584128/What-is-the-difference-between-equalsequals-and-Eq

==

O operador == pode ser usada para comparar duas variáveis ??de qualquer tipo, e ele simplesmente compara os bits .

int a = 3;
byte b = 3;
if (a == b) { // true }

Nota:. Há mais zeros no lado esquerdo do int, mas não se preocupam com isso aqui

int a (00000011) == byte b (00000011)

Lembre-se == cuidados operador só sobre o padrão dos bits na variável.

Uso == Se duas referências (primitivos) refere-se ao mesmo objecto na pilha.

As regras são mesmo se a variável é uma referência ou primitiva.

Foo a = new Foo();
Foo b = new Foo();
Foo c = a;

if (a == b) { // false }
if (a == c) { // true }
if (b == c) { // false }

a == c é verdadeiro a == b é false

o padrão de bits são os mesmos para A e C, então eles são iguais usando ==.

Equal ():

Use as equals () método para ver se dois objetos diferentes são iguais .

Tal como duas cordas diferentes objetos que ambos representam os personagens em "Jane"

A única diferença entre Equal e == é em comparação tipo de objeto. em outros casos, tais como os tipos de referência e tipos de valor, que são quase os mesmos (quer ambos são igualdade bit a bit ou ambos são igualdade de referência).

objeto: Igual a: bit-wise igualdade ==: igualdade de referência

string: (igual e == são as mesmas para corda, mas se uma das cordas alterado para objeto, então resultado de comparação será diferente) Igual a: bit-wise igualdade ==: igualdade bit-wise

aqui para mais explicações.

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