문제

실버 라이트 애플리케이션에 2 개의 문자열을 비교하는 조건이 있습니다. == 돌아옵니다 거짓 동안 .Equals() 보고 진실.

코드는 다음과 같습니다.

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

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

왜 이런 일이 일어나고 있는지에 대한 이유가 있습니까?

도움이 되었습니까?

해결책

언제 == 유형의 표현에 사용됩니다 object, 그것은 해결할 것입니다 System.Object.ReferenceEquals.

Equals 그냥 a virtual 방법과 동작이 있으므로 재정의 버전이 사용됩니다 ( string 유형은 내용을 비교합니다).

다른 팁

객체 참조를 문자열과 비교할 때 (객체 참조가 문자열을 지칭하는 경우에도) == 문자열 클래스에 특정한 연산자는 무시됩니다.

일반적으로 (현을 다루지 않을 때, 즉), Equals 비교 가치, 동안 == 비교 객체 참조. 비교하는 두 개의 객체가 객체의 동일한 정확한 인스턴스를 참조하는 경우, 둘 다 True를 반환하지만 하나는 동일한 내용을 가지고 있고 다른 소스에서 나온 경우 (동일한 데이터를 가진 별도의 인스턴스). 진실을 반환하십시오. 그러나 주석에 언급 된 바와 같이 문자열은 특별한 경우입니다. == 연산자는 정당하게 문자열 참조 (객체 참조가 아님)를 처리 할 때 별도의 인스턴스 인 경우에도 값 만 비교됩니다. 다음 코드는 행동의 미묘한 차이를 보여줍니다.

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

출력은 다음과 같습니다.

True True True
False True True
False False True

== 그리고 .Equals 둘 다 실제 유형에 정의 된 동작과 통화 사이트의 실제 유형에 따라 다릅니다. 둘 다 단지 모든 유형에서 무시할 수있는 방법 / 연산자 일 뿐이며 저자가 원하는 행동이 주어집니다. 내 경험상 사람들이 구현하는 것이 일반적이라고 생각합니다. .Equals 객체에서는 연산자를 구현하는 것을 소홀히합니다 ==. 이것은 그것을 의미합니다 .Equals 실제로 값의 평등을 측정합니다 == 그들이 동일한 참조인지 여부를 측정합니다.

정의가 플럭스 또는 일반 알고리즘을 작성하는 새로운 유형으로 작업 할 때 가장 모범 사례가 다음과 같습니다.

  • C#의 참조를 비교하려면 사용합니다. Object.ReferenceEquals 직접 (일반적인 경우에는 필요하지 않음)
  • 내가 사용하는 값을 비교하려면 EqualityComparer<T>.Default

어떤 경우에는 내가 사용한다고 느낄 때 == 모호합니다. 명시 적으로 사용할 것입니다 Object.Reference 모호성을 제거하기 위해 코드와 동일합니다.

Eric Lippert는 최근 CLR에 2 가지 평등 방법이있는 이유에 대한 블로그 게시물을 수행했습니다. 읽을 가치가 있습니다

첫째, 거기 ~이다 차이. 숫자

> 2 == 2.0
True

> 2.Equals(2.0)
False

그리고 끈을 위해

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

> x.Equals(null)
NullReferenceException

두 경우 모두 == 보다 유용하게 행동합니다 .Equals

객체를 문자열에 던지면 올바르게 작동한다고 덧붙입니다. 이것이 바로 컴파일러가 당신에게 경고를주는 이유입니다.

의도하지 않은 참조 비교; 값 비교를 얻으려면 왼쪽을 'String'유형으로 캐스팅하십시오.

== 운영자1. 피연산자 인 경우 가치 유형 그리고 그들의 가치는 같고, 다른 거짓을 반환합니다. 2. 피연산자 인 경우 참조 유형 문자열을 제외하고 둘 다 동일한 객체를 참조하면 true one false를 반환합니다. 3. 피연산자가 문자열 유형이고 그 값이 같으면 다른 값을 반환합니다.

.equals1. 피연산자가 기준 유형 인 경우 수행됩니다 참조 평등 즉, 둘 다 동일한 객체를 참조하면 true false를 반환합니다. 2. 피연산자가 값 유형 인 경우 == 운영자와 달리 유형을 먼저 확인하고 유형이 동일하면 수행 == 운영자는 거짓을 반환합니다.

내가 이해하는 한 답은 간단합니다.

  1. == 객체 참조를 비교합니다.
  2. .equals는 객체 내용을 비교합니다.
  3. 문자열 데이터 유형은 항상 컨텐츠 비교처럼 작동합니다.

나는 내가 옳기를 바랍니다. 그것은 당신의 질문에 대답했습니다.

정적 버전의 .Equal 방법은 지금까지 언급되지 않았으며, 여기에 이것을 추가하여 3 가지 변형을 요약하고 비교하고 싶습니다.

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

어디 MyString 코드의 다른 곳에서 나오는 변수입니다.

배경 정보 및 여름 화 :

Java 사용을 사용합니다 == 문자열을 비교하려면 사용해서는 안됩니다. 두 언어를 모두 사용해야하고 또한 == C#에서 더 나은 것으로 대체 할 수도 있습니다.

C#에서는 두 가지 유형 문자열 인 한 방법 1 또는 방법 2를 사용하여 문자열을 비교할 수있는 실질적인 차이는 없습니다. 그러나 하나가 NULL, 하나는 다른 유형 (정수와 같은)이거나 다른 참조를 갖는 객체를 나타내는 경우, 초기 질문에서 볼 수 있듯이 평등의 내용을 비교하는 것이 무엇을 반환하지 않을 수 있음을 경험할 수 있습니다. 당신은 기대합니다.

제안 된 솔루션 :

사용하기 때문에 == 사용과 정확히 동일하지 않습니다 .Equals 물건을 비교할 때는 사용할 수 있습니다 정적 문자열 대신 방법. 이런 식으로, 양측이 동일한 유형이 아닌 경우에도 여전히 내용을 비교하고 하나가 널이면 예외를 피할 수 있습니다.

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

글을 쓰는 것이 조금 더 있지만, 제 생각에는 사용이 더 안전합니다.

다음은 Microsoft에서 복사 한 정보입니다.

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

매개 변수

a

비교할 첫 번째 문자열, 또는 null.

b

비교할 두 번째 문자열, 또는 null.

보고 Boolean

true 값의 경우 a 값과 동일합니다 b; 그렇지 않으면, false. 둘 다 a 그리고 b ~이다 null, 메소드가 반환됩니다 true.

나는 여기서 약간 혼란스러워합니다. 런타임 유형의 컨텐츠 유형이 String 유형 인 경우 모두 == 및 Equals는 True를 반환해야합니다. 그러나 이것이 사실이 아닌 것처럼 보이므로 런타임 유형의 컨텐츠 유형이 문자열이 아니며 동등한 호출은 참조 평등을 수행하고 있으며, 이는 동등한 이유 ( "에너지 공격")가 실패하는 이유를 설명합니다. 그러나 두 번째 경우, 과부하가있는 == 정적 연산자를 호출 해야하는 결정은 컴파일 시간에 이루어 지며이 결정은 == (문자열, 문자열) 인 것으로 보입니다. 이것은 내용이 문자열로 암시 적 변환을 제공한다는 것을 나에게 제안합니다.

@bluemonkmn의 이전 답변에는 또 다른 차원이 있습니다. 추가 차원은 @drahcir의 제목 질문에 대한 답이 언급 된 바와 같이 어떻게 우리는 string 값. 설명하려면 :

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

출력은 다음과 같습니다.

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

답을 하나 더 추가합니다.

.EqualsTo() 방법은 문화와 사례 민감성과 비교할 수있는 규정을 제공합니다.

이미 좋은 답변에 추가 된 것처럼 :이 동작은 현에 국한되지 않거나 다른 번호 유형을 비교하지 않습니다. 두 요소가 동일한 기본 유형의 유형 객체 인 경우에도. "=="는 작동하지 않습니다.

다음 스크린 샷은 두 객체 {int} - 값 비교 결과를 보여줍니다.

Example From VS2017

그만큼 == C#의 토큰은 두 가지 평등 확인 연산자에게 사용됩니다. 컴파일러가 해당 토큰을 만나면 비교되는 유형 중 하나가 비교되는 특정 조합 유형 (*)에 대한 평등 작동기 과부하 또는 두 유형을 변환 할 수있는 유형의 조합에 대해 구현했는지 확인합니다. 컴파일러가 그러한 과부하를 찾으면 사용합니다. 그렇지 않으면 두 유형이 참조 유형이고 관련된 클래스가 아닌 경우 (인터페이스 일 수도 있고 관련 클래스 일 수 있음) 컴파일러는 고려됩니다. == 참조 비교 연산자로서. 조건이 없으면 편집이 실패합니다.

다른 언어는 두 평등 확인 연산자에게 별도의 토큰을 사용합니다. 예를 들어 vb.net에서 = 토큰은 과부하 가능한 평등 확인 연산자에게만 표현식 내에서 사용됩니다. Is 참조 테스트 또는 널 테스트 연산자로 사용됩니다. 사용해야합니다 = 평등 확인 연산자를 무시하지 않는 유형에서 사용하려고 시도하는 것처럼 실패합니다. Is 참조 평등 또는 무효화를 테스트하는 것 이외의 목적으로.

(*) 유형은 일반적으로 자체와 비교하기 위해 평등 만 과부하 만이지만 다른 특정 유형과 비교하기 위해 평등 연산자에 과부하하는 것이 유용 할 수 있습니다. 예를 들어, int (그리고 IMHO는 평등 연산자를 정의 할 수 있었을 수도 있습니다. float, 16777217은 16777216f와 동일하게보고하지 않습니다. 그대로, 그러한 연산자가 정의되지 않기 때문에 C#은 int 에게 float, 평등-점검 연산자가보기 전에 16777216F로 반올림; 그 연산자는 두 개의 동일한 부동 소수점 번호를보고, 반올림을 알지 못한다고보고합니다.

정말 훌륭한 답변과 예!

둘 사이의 근본적인 차이를 추가하고 싶습니다.

다음과 같은 연산자 == 다형성이 아닙니다 Equals ~이다

그 개념을 염두에두고, 당신이 예제를 알아 내면 (왼손과 오른손 참조 유형을보고, 유형에 실제로 == 운영자가 과부하되어 있고 재정의되는지 확인/아는 경우) 올바른 답을 얻을 수 있습니다. .

객체를 만들 때 객체에 두 부분이 있습니다. 하나는 내용이고 다른 하나는 해당 내용을 참조합니다.== 내용과 참조를 모두 비교합니다.equals() 내용 만 비교합니다

http://www.codeproject.com/articles/584128/what-is-difference-between-equal equals-and-eq

==

== 연산자는 모든 종류의 두 변수를 비교하는 데 사용될 수 있으며 그것은 단순히 비트를 비교합니다.

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

참고 : INT의 왼쪽에는 더 많은 제로가 있지만 여기서는 신경 쓰지 않습니다.

int a (00000011) == 바이트 B (00000011)

기억 == 운영자는 변수의 비트 패턴에 대해서만 관심이 있습니다.

사용 == 두 참조 (프리미티브)가 힙의 동일한 물체를 나타냅니다.

변수가 기준이든 원시인지 여부에 관계없이 규칙이 동일합니다.

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는 true a == b는 false입니다.

비트 패턴은 A와 C의 경우 동일하므로 ==를 사용하여 동일합니다.

동일한():

equals () 메소드를 사용하여 볼 수 있습니다 두 개의 다른 객체가 동일하다면.

"Jane"의 문자를 나타내는 두 개의 다른 문자열 객체와 같은

동일과 ==의 유일한 차이점은 객체 유형 비교입니다. 기준 유형 및 값 유형과 같은 다른 경우에는 거의 동일합니다 (둘 다 비록 평등하거나 참조 평등입니다).

개체 : 동등한 평등 == : 참조 평등

문자열 : (Equals 및 ==는 문자열에 대해 동일하지만 문자열 중 하나가 객체로 변경되면 비교 결과가 다릅니다)와 동일 : 비트 별 평등 == : 비트 별 평등

보다 여기 자세한 설명.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top