==와 같음 ()의 C # 차이
실버 문자열 응용 프로그램에서 2 개의 문자열을 비교하는 조건이 있습니다. 어떤 이유로 사용 ==
하면 true 를 .Equals()
반환하고 false 를 반환 합니다 .
코드는 다음과 같습니다.
if (((ListBoxItem)lstBaseMenu.SelectedItem).Content.Equals("Energy Attack"))
{
// Execute code
}
if (((ListBoxItem)lstBaseMenu.SelectedItem).Content == "Energy Attack")
{
// Execute code
}
왜 이런 일이 발생하는지에 대한 이유가 있습니까?
때 ==
유형의 표현에 사용되는 object
, 그것은에 해결할 수 있습니다 System.Object.ReferenceEquals
.
Equals
는 virtual
메소드 일 뿐이며 이와 같이 동작하므로 재정의 된 버전이 사용됩니다 ( string
유형은 내용을 비교합니다).
객체 참조를 문자열과 비교할 때 (객체 참조가 문자열을 참조하더라도) ==
문자열 클래스에 특정한 연산자 의 특수 동작 은 무시됩니다.
(인 스트링을 처리하지 않는) 통상은, Equals
비교 값을 동시에 ==
비교 객체 참조 . 비교하는 두 객체가 동일한 객체의 동일한 인스턴스를 참조하는 경우 둘 다 true를 반환하지만, 하나의 내용이 동일하고 다른 소스에서 온 경우 (데이터가 동일한 별도의 인스턴스 임) 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
객체 에 구현 하는 것이 일반적 이지만 operator 구현은 무시하는 것이 일반적입니다 ==
. 이는 .Equals
실제로 값의 동일성을 ==
측정하는 동시에 동일한 참조인지 여부를 측정합니다.
정의가 유동적이거나 일반 알고리즘을 작성하는 새로운 유형으로 작업 할 때 가장 좋은 방법은 다음과 같습니다.
- C #에서 참조를 비교하려면
Object.ReferenceEquals
직접 사용 하십시오 (일반적인 경우에는 필요하지 않음) - 내가 사용하는 값을 비교하려면
EqualityComparer<T>.Default
어떤 경우에는 사용법 ==
이 모호 하다고 생각 되면 명확하게 Object.Reference
코드에서 equals를 사용 하여 모호성을 제거합니다.
에릭 리퍼 트 (Eric Lippert)는 최근 CLR에 두 가지 평등 방법이있는 이유에 대한 블로그 게시물을 작성했습니다. 읽을 가치가 있습니다
첫째, 거기 이다 차이. 숫자
> 2 == 2.0
True
> 2.Equals(2.0)
False
그리고 문자열
> string x = null;
> x == null
True
> x.Equals(null)
NullReferenceException
두 경우 모두 ==
보다 더 유용하게 작동합니다.Equals
객체를 문자열로 캐스팅하면 올바르게 작동한다고 덧붙입니다. 이것이 컴파일러가 경고 메시지를 표시하는 이유입니다.
의도하지 않은 기준 비교; 값을 비교하려면 왼쪽을 'string'유형으로 캐스트하십시오.
내가 이해하는 한 대답은 간단합니다.
- == 객체 참조를 비교합니다.
- 같음은 객체 내용을 비교합니다.
- 문자열 데이터 유형은 항상 내용 비교처럼 작동합니다.
나는 내가 정확하고 그것이 당신의 질문에 대답하기를 바랍니다.
== 연산자 1. 피연산자가 값 유형 이고 해당 값이 같으면 true를 반환하고 그렇지 않으면 false를 반환합니다. 2. 피연산자가 문자열을 제외한 참조 유형 이고 둘 다 동일한 오브젝트를 참조하는 경우 true를 리턴하고 그렇지 않으면 false를 리턴합니다. 3. 피연산자가 문자열 유형이고 해당 값이 동일한 경우 true를 리턴하고 그렇지 않으면 false를 리턴합니다.
.Equals 1. 피연산자가 Reference Types이면 Reference Equality 를 수행 합니다. 둘 다 동일한 객체를 참조하면 true를 반환하고 그렇지 않으면 false를 반환합니다. 2. 피연산자가 값 유형 인 경우 == 연산자와 달리 유형을 먼저 확인하고 유형이 같은 경우 == 연산자를 수행하고 그렇지 않으면 false를 리턴합니다.
.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
사물을 비교할 때 사용하는 것과 정확히 동일하지 않으므로 정적 String.Equals 메서드를 대신 사용할 수 있습니다 . 이 방법으로 양면이 같은 유형이 아닌 경우에도 내용을 비교하고 한쪽이 null이면 예외를 피할 수 있습니다.
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
.
나는 여기에 약간 혼란 스럽다. Content의 런타임 유형이 문자열 유형 인 경우 ==와 Equals는 모두 true를 리턴해야합니다. 그러나 이것이 사실이 아닌 것처럼 보이기 때문에 런타임 유형의 Content가 문자열이 아니며 Equals를 호출하면 참조 평등이 수행되고 Equals ( "Energy Attack")가 실패하는 이유를 설명합니다. 그러나 두 번째 경우에는 오버로드 된 == 정적 연산자를 호출해야하는 결정이 컴파일 시간에 이루어지며이 결정은 == (string, string) 인 것으로 보입니다. 이것은 Content가 문자열에 대한 암시 적 변환을 제공한다는 것을 나에게 제안합니다.
@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}-값을 비교 한 결과를 보여줍니다.
==
C # 의 토큰은 두 개의 다른 등식 검사 연산자에 사용됩니다. 컴파일러가 해당 토큰을 발견하면 비교중인 유형 중 하나가 비교중인 특정 조합 유형 (*) 또는 두 유형을 변환 할 수있는 유형 조합에 대해 동등 연산자 오버로드를 구현했는지 확인합니다. 컴파일러가 이러한 과부하를 찾으면이를 사용합니다. 그렇지 않으면 두 유형이 모두 참조 유형이고 관련이없는 클래스가 아닌 경우 (인터페이스이거나 관련 클래스 일 수 있음) 컴파일러는 ==
참조 비교 연산자로 간주 합니다. 두 조건이 모두 적용되지 않으면 컴파일이 실패합니다.
일부 다른 언어는 두 개의 동등 검사 연산자에 대해 별도의 토큰을 사용합니다. 예를 들어 VB.NET에서 =
토큰은 오버로드 가능한 동등성 검사 연산자에 대해서만 식 내에서 Is
사용되며 참조 테스트 또는 null 테스트 연산자로 사용됩니다. 참조 동등성 또는 널 (NULL)을 테스트하는 것 이외의 다른 목적 =
으로 사용하려고하면 동등성 검사 연산자를 대체하지 않는 유형에 대한 사용 은 실패 Is
합니다.
(*) 유형은 일반적으로 자체와 비교하기 위해 과부하 평등에만 해당되지만 유형이 다른 특정 유형과 비교하기 위해 평등 연산자에 과부하를주는 것이 유용 할 수 있습니다. 예를 들어, 16777217은 16777216f와 동일하게보고하지 않도록 int
등호 연산자를 (와 float
) 비교하여 등호 연산자를 정의 할 수있었습니다 (및 IMHO가 정의 했어야하지만 그렇지 않은 경우) . 그대로, 그러한 연산자가 정의되어 있지 않기 때문에 C #은 int
to 를 승격 float
시켜 등식 검사 연산자가보기 전에 16777216f로 반올림합니다. 그런 다음 해당 연산자는 두 개의 동일한 부동 소수점 숫자를보고 발생 된 반올림을 인식하지 못하고 동일한 것으로보고합니다.
정말 좋은 답변과 예!
둘 사이의 근본적인 차이점을 추가하고 싶습니다.
==
다형성이 아닌 연산자Equals
는
이 개념을 염두에두고 왼손 및 오른손 참조 유형을보고 유형에 실제로 과부하가 걸리고 Equals가 재정의되는지 확인 / 알아서 예제를 수행하면 올바른 대답을 얻을 수 있습니다. .
객체를 만들 때 객체에 대한 두 부분이 있습니다. 하나는 내용이고 다른 하나는 그 내용을 참조합니다. ==
내용과 참조를 모두 비교합니다. equals()
내용 만 비교
http://www.codeproject.com/Articles/584128/What-is-the-difference-between-equalsequals-and-Eq
==
== 연산자는 모든 종류의 두 변수를 비교하는 데 사용될 수 있으며 단순히 비트를 비교합니다 .
int a = 3;
byte b = 3;
if (a == b) { // true }
참고 : int의 왼쪽에는 더 많은 0이 있지만 여기서는 신경 쓰지 않습니다.
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"의 문자를 나타내는 두 개의 다른 String 객체와 같은
같음과 ==의 유일한 차이점은 객체 유형 비교에 있습니다. 참조 유형 및 값 유형과 같은 다른 경우에는 거의 동일합니다 (둘 다 비트 단위 평등 또는 둘 다 참조 평등).
객체 : 같음 : 비트 별 같음 == : 참조 같음
문자열 : (문자열과 같음 = =는 동일하지만 문자열 중 하나가 객체로 변경되면 비교 결과가 달라집니다) 같음 : 비트 별 같음 == : 비트 별 같음
참고 URL : https://stackoverflow.com/questions/814878/c-sharp-difference-between-and-equals
'Programming' 카테고리의 다른 글
JavaScript에서 null 값을 확인하려면 어떻게합니까? (0) | 2020.02.12 |
---|---|
하나의 로그 회전 검사를 수동으로 실행할 수 있습니까? (0) | 2020.02.12 |
Swift 언어에서 느낌표는 무엇을 의미합니까? (0) | 2020.02.11 |
C ++ 컴파일이 왜 그렇게 오래 걸립니까? (0) | 2020.02.11 |
SQL Server VARCHAR / NVARCHAR 문자열에 줄 바꿈을 삽입하는 방법 (0) | 2020.02.11 |