[C#] C #에서 프리미티브의 ==와 Equals ()의 차이점은 무엇입니까?

이 코드를 고려하십시오.

int age = 25;
short newAge = 25;
Console.WriteLine(age == newAge);  //true
Console.WriteLine(newAge.Equals(age)); //false
Console.ReadLine();

intshort기본 유형이지만 둘 과 의 비교 ==는 true 를 리턴하고 비교 Equals는 false 를 리턴합니다.

왜?



답변

짧은 답변:

평등은 복잡합니다.

자세한 답변 :

기본 요소 유형은 기본을 대체하고 object.Equals(object)상자 object가 동일한 유형 및 값인 경우 true를 리턴합니다 . (널링 가능 유형에서도 작동합니다. 널이 아닌 널 입력 가능 유형은 항상 기본 유형의 인스턴스에 적용됩니다.)

newAgeis 이므로 동일한 값으로 boxed short 를 전달하면 short해당 Equals(object)메소드 만 true를 리턴합니다 . boxed를 전달 하므로 false를 반환합니다.int

대조적으로, ==연산자는 2 int초 (또는 1 short초) 를 취하는 것으로 정의됩니다 long.
당신이 그것을 호출 할 때 intshort, 컴파일러는 암시 적으로 변환됩니다 shortint그 결과 비교 int값으로들.

그것을 작동시키는 다른 방법들

기본 유형 Equals()에는 동일한 유형을 허용하는 자체 메소드 도 있습니다 .
작성 age.Equals(newAge)하면 컴파일러 int.Equals(int)에서 최상의 과부하를 선택 하고 암시 적으로로 변환 short합니다 int. true이 메소드는 단순히 ints를 직접 비교하기 때문에을 리턴 합니다.

short또한 short.Equals(short)메소드가 있지만 int암시 적으로로 변환 short할 수 없으므로 호출하지 않습니다.

캐스트 로이 메소드를 강제로 호출 할 수 있습니다.

Console.WriteLine(newAge.Equals((short)age)); // true

이것은 short.Equals(short)권투없이 직접 호출 합니다. 경우 age32767보다 큰, 그것은 오버 플로우 예외가 발생합니다.

short.Equals(object)오버로드를 호출 할 수도 있지만 박스형 객체를 명시 적으로 전달하여 동일한 유형을 얻습니다.

Console.WriteLine(newAge.Equals((object)(short)age)); // true

이전 대안과 마찬가지로,에 맞지 않으면 오버플로가 발생합니다 short. 이전 솔루션과 달리 short시간과 메모리를 낭비하여 객체를 상자에 넣습니다.

소스 코드:

Equals()실제 소스 코드의 두 가지 방법은 다음과 같습니다 .

    public override bool Equals(Object obj) {
        if (!(obj is Int16)) {
            return false;
        }
        return m_value == ((Int16)obj).m_value;
    }

    public bool Equals(Int16 obj)
    {
        return m_value == obj;
    }

추가 자료 :

Eric Lippert를 참조하십시오 .


답변

이 때문에 대한 과부하 short.Equals그은을지지 않습니다 int. 따라서 이것을 다음이라고합니다.

public override bool Equals(object obj)
{
    return obj is short && this == (short)obj;
}

obj하지 않은 것이다 short.. 따라서,이 거짓.


답변

Equals에 전달하면 다음과 같이 전달 int됩니다 .shortobject

여기에 이미지 설명을 입력하십시오
따라서이 의사 코드는 다음과 같이 실행됩니다.

return obj is short && this == (short)obj;


답변

값 형식의 .Equals경우 두 개체의 형식이 동일하고 값이 같아야하지만 ==두 값이 같은지 테스트 만하면됩니다.

Object.Equals
http://msdn.microsoft.com/en-us/library/bsc2ak47(v=vs.110).aspx


답변

==동일한 조건을 확인하는 데 사용되며 연산자 (부울 연산자)로 간주 될 수 있습니다. 단지 2 가지를 비교하기 위해 여기에서 유형 캐스팅이 수행되므로 데이터 유형은 중요하지 않으며 Equals동등 조건을 확인하는 데에도 사용됩니다 그러나이 경우 데이터 유형이 동일해야합니다. N 같음은 연산자가 아닌 방법입니다.

아래는 귀하가 제공 한 것에서 가져온 작은 예이며 차이점을 간략하게 설명합니다.

int x=1;
short y=1;
x==y;//true
y.Equals(x);//false

위의 예에서 X와 Y는 같은 값, 즉 1을 사용 ==하며, 를 사용할 때 ==컴파일러가 short 유형을 int로 변환하여 결과를 제공하면 true를 반환합니다 .

우리가 사용할 때 Equals비교는 수행되지만 형식 캐스팅은 컴파일러에 의해 수행되지 않으므로 false가 반환됩니다.

여러분, 제가 틀렸다면 알려주십시오.


답변

메소드 또는 연산자 인수가 필수 유형이 아닌 많은 컨텍스트에서 C # 컴파일러는 암시 적 유형 변환을 수행하려고 시도합니다. 컴파일러가 암시 적 변환을 추가하여 모든 인수가 연산자와 메서드를 만족시킬 수 있다면 경우에 따라 (특히 평등 테스트의 경우) 결과가 놀라 울 수도 있지만 불만없이 처리 할 수 ​​있습니다.

또한, 각각의 값 유형 은 값의 종류와 객체의 종류 (*)를 설명 int하거나 short실제로 설명합니다. 값을 다른 종류의 값으로 변환하고 모든 종류의 값을 해당하는 종류의 개체로 변환하기위한 암시 적 변환이 있지만 서로 다른 종류의 개체는 서로 암시 적으로 변환 할 수 없습니다.

하나는 사용하는 경우 ==비교 연산자 short와을 int의이 short암시 적으로 변환됩니다 int. 그 수치의 그 동일이라면 int1, int이 동등한 것이다 전환시켰다되는 int이 비교되는이. 그러나 Equals짧은 방법 을 사용 하여을 비교 하려고 시도하는 경우 메서드 int의 과부하를 충족시키는 암시 적 변환은에 Equals해당하는 객체 유형으로 변환하는 것 int입니다. short전달 된 객체와 일치하는지 여부를 묻는 메시지가 표시 되면 해당 객체 int가 a 가 아니라 관찰되어 short동일하지 않을 수 있다는 결론을 내립니다.

일반적으로 컴파일러는 그것에 대해 불평하지 않지만 같은 유형이 아닌 것을 비교하지 않아야합니다. 사물을 공통 형식으로 변환하는 것이 동일한 결과를 낼 것인지에 관심이 있다면, 그러한 변환을 명시 적으로 수행해야합니다. 예를 들어,

int i = 16777217;
float f = 16777216.0f;

Console.WriteLine("{0}", i==f);

inta와 a 를 비교할 수있는 세 가지 방법이 있습니다 float. 알고 싶은 사람 :

  1. 가장 가까운 float값이 int일치 float합니까?
  2. float일치하는 정수 부분이 int?
  3. 를 수행 int하고 float동일한 수치를 나타냅니다.

하나는 비교하려고하면 intfloat직접 컴파일 된 코드는 첫 번째 질문에 대답 할 것이다; 그러나 이것이 프로그래머가 의도 한 것과는 거리가 멀다. 비교를 변경하면 (float)i == f첫 번째 의미가 의도되었다는 것이 분명해 지거나 (double)i == (double)f코드가 세 번째 질문에 대답하게 될 것입니다 (그리고 그것이 의도 한 것임을 분명히합니다).

(*) C # 사양이 유형의 값을 예 System.Int32를 들어 유형 의 객체로 간주하더라도 System.Int32, 이러한 견해는 값과 객체를 다른 우주에 거주하는 것으로 간주하는 플랫폼에서 코드를 실행해야한다는 요구 사항과 모순됩니다. 또한,이 경우 T참조 형식이며, xA는 T다음 유형의 참조 T를 참조 할 수 있어야한다 x. 따라서 v유형 의 변수 Int32가을 보유하는 경우 유형 Object의 참조는 해당 내용에 Object대한 참조를 보유 할 수 있어야합니다 v. 실제로 형식의 참조는 Object에서 복사 된 데이터를 보유 v하고 있지만 v자체 또는 내용 을 가리키는 개체를 가리킬 수 있습니다 . 그것은 제안하지 않을 것입니다v그것의 내용은 실제로입니다 Object.


답변

같음 () 의 방법 으로 System.Object 클래스
구문 : 공공 가상 부울 같음 ()
추천 우리는 두 객체의 상태는 우리가 사용해야 비교하려는 경우 ) (같음 방법

위에서 언급했듯이 답변 == 연산자는 값이 동일 하다는 것을 비교합니다.

ReferenceEqual과 혼동하지 마십시오

Reference Equals ()
구문 : public static bool ReferenceEquals ()
지정된 객체 인스턴스가 동일한 인스턴스인지 확인합니다.