C\#의==연산 자
연산 자 와 기원 유형연산 자 와 인용 유형연산 자 와 String 유형연산 자 와 값 유형연산 자 와 범 형
==연산 자 와 기본 형식
우 리 는 각각 두 가지 방식 으로 두 정 수 를 비교 하 는데 첫 번 째 는 Equals(int)방법 을 사용 하고 두 번 째 는==연산 자 를 사용한다.
 class Program
 {
   static void Main(String[] args)
   {
     int num1 = 5;
    int num2 = 5;
     Console.WriteLine(num1.Equals(num2));
    Console.WriteLine(num1 == num2);
  }
 } 
 만약 에 이전에 IL 명령 을 접 한 적 이 없 지만 괜 찮 습 니 다.여기 서 모든 명령 을 이해 할 필요 가 없습니다.저 희 는 이 두 가지 비교 방식 의 차 이 를 알 고 싶 을 뿐 입 니 다.
이 줄 의 코드 를 볼 수 있 습 니 다:
  IL_0008: call    instance bool [mscorlib]System.Int32::Equals(int32)이제 사용==연산 자가 생 성 된 IL 명령 어 를 살 펴 보 겠 습 니 다.
 IL_0015: ceq==연산 자 와 인용 유형
위의 예제 코드 를 수정 하고 int 형식 을 참조 형식 으로 바 꾸 며 컴 파일 한 후 ildasm.exe 도 구 를 통 해 IL 코드 를 역 컴 파일 하여 봅 니 다.
 class Program
 {
   static void Main(String[] args)
   {
     Person p1 = new Person();
     p1.Name = "Person1";
     Person p2 = new Person();
    p2.Name = "Person1";
    Console.WriteLine(p1.Equals(p2));
    Console.WriteLine(p1 == p2);
  }
 } 
 우 리 는 p1.Equals(p2)코드 를 보 았 습 니 다.이것 은 Object.Equals(Object)의 가상 방법 을 호출 하여 비교 하 는 것 입 니 다.이것 은 예 상 했 던 일 입 니 다.현재 우리 가 보기에==연산 자가 생 성 한 IL 코드 는 기본 형식 과 일치 하 며,사용 하 는 것 도 ceq 명령 이다.
==연산 자 와 String 형식
String 형식의 예 를 들 어 보 겠 습 니 다.
class Program
 {
   static void Main(String[] args)
   {
     string s1 = "Sweet";
     string s2 = String.Copy(s1);
     Console.WriteLine(ReferenceEquals(s1, s2));
     Console.WriteLine(s1 == s2);
    Console.WriteLine(s1.Equals(s2));
  }
 }위의 코드 를 실행 하고 콘 솔 에서 출력 한 결 과 는 다음 과 같 습 니 다.
 
 Reference Equals 가 false 로 돌아 가 는 것 을 볼 수 있 습 니 다.이 두 변 수 는 서로 다른 인 스 턴 스 임 을 의미 하지만=연산 자 와 Equals 방법 은 모두 true 입 니 다.String 형식 에서==연산 자가 실행 한 결 과 는 Equals 가 실행 한 결과 와 같 습 니 다.
마찬가지 로 우 리 는 ildasm.exe 도 구 를 사용 하여 IL 코드 를 생 성 하 는 것 을 역 컴 파일 한 적 이 있다.
 
 여기 서 우 리 는 ceq 명령 을 보지 못 했 습 니 다.String 형식 에 대해=연산 자 를 똑 같이 판단 할 때 호출 하 는 것 은 op 입 니 다.equality(string,string)의 새로운 방법 입 니 다.이 방법 은 두 개의 String 형식의 매개 변수 가 필요 합 니 다.그러면 이것 은 도대체 무엇 입 니까?
정 답 은 String 형식 이==연산 자의 재 부팅 을 제공 합 니 다.C\#에서 우리 가 하나의 유형 을 정의 할 때,우 리 는 이 유형의=연산 자 를 다시 불 러 올 수 있 습 니 다.예 를 들 어 예전 의 예 에서 우리 가 실현 한 Person 류 에 대해 만약 에 우리 가 그것 을 위해=연산 자 를 다시 불 러 오 면 대체적인 코드 는 다음 과 같다.
public class Person
 {
   public string Name { get; set; }
   public static bool operator ==(Person p1, Person p2)
  {
    //         ==,     StackOverflowException
    if (ReferenceEquals(p1, p2))
       return true; 
    if (ReferenceEquals(p1, null) || ReferenceEquals(p2, null)) 
      return false; 
     return p1.Name == p2.Name;
   } 
   public static bool operator !=(Person p1, Person p2)
   {
    return !(p1 == p2);
   }
 }일 을 더욱 분명하게 하기 위해 서,우 리 는 마이크로소프트 가 실현 한 String 유형 을 살 펴 보 았 다.
 
 위의 캡 처 에서 우 리 는 두 개의 연산 자의 과부하 가 있 고 하 나 는 같 으 며 다른 하 나 는 부등식 연산 자 이 며 그 연산 방식 은 완전히 같 지만 부정 은 연산 자 출력 과 같다 는 것 을 볼 수 있다.주의해 야 할 것 은,만약 당신 이 한 종류의=실행 문자 의 실현 을 다시 불 러 오 려 면,다시 불 러 와 야 한 다 는 것 입 니 다!=조작 부호 의 실현,그렇지 않 으 면 컴 파일 이 잘못 될 것 이다.
==연산 자 와 값 형식
프 리 젠 테 이 션 값 형식의 예제 전에 Person 형식 을 참조 형식 에서 값 형식 으로 바 꿉 니 다.Person 은 다음 과 같이 정의 합 니 다.
public struct Person
 {
   public string Name { get; set; }
   public Person(string name)
   {
     Name = name;
   }
   public override string ToString()
   {
     return Name;
   }
 }
 class Program
  {
    static void Main(String[] args)
    {
      Person p1 = new Person("Person1");
      Person p2 = new Person("Person2");
      Console.WriteLine(p1.Equals(p2));
      Console.WriteLine(p1 == p2);
   }
 } 
 오류 알림 에 따라 우 리 는 Person 구조 체 의==연산 자 를 다시 불 러 와 야 합 니 다.다시 불 러 오 는 문 구 는 다음 과 같 습 니 다(구체 적 인 논 리 를 무시 합 니 다).
 public static bool operator ==(Person p1, Person p2)
 {
 }
 public static bool operator !=(Person p1, Person p2)
 {
 }값 유형 에 대해 서 는 Equals(object)방법 을 다시 쓰 지 않 을 때 이 방법 이 실현 되 는 원 리 는 모든 필드 를 반사 적 으로 옮 겨 다 니 며 각 필드 의 동일성 을 검사 하 는 것 입 니 다.이 점 에 대해 서 는 설명 하지 않 습 니 다.값 형식 에 대해 서 는 이 방법 을 다시 쓰 는 것 이 좋 습 니 다.
==연산 자 와 범 형
우 리 는 다른 예제 코드 를 작성 하여 두 개의 String 형식 변 수 를 설명 하고 4 가지 다른 방식 으로 비교 연산 을 합 니 다.
 public class Program
 {
   public static void Main(string[] args)
   {
     string str = "Sweet";
     string str = string.Copy(str);
     Console.WriteLine(ReferenceEquals(str, str1));
     Console.WriteLine(str.Equals(str1));
     Console.WriteLine(str == str1);
     Console.WriteLine(object.Equals(str, str1));
  }
 } 
 우선,우 리 는 Reference Equals 방법 을 사용 하여 두 개의 String 변 수 를 똑 같이 인용 한 것 으로 판단 합 니 다.그 다음 에 우 리 는 인 스 턴 스 방법 Equals(string)를 사용 합 니 다.세 번 째 줄 에서 우 리 는=연산 자 를 사용 합 니 다.마지막 으로 정적 방법 Object.quals(object,object)를 사용 합 니 다.(이 방법 은 최종 적 으로 String 형식 으로 재 작성 한 Object.Equals(object)방법 을 사용 합 니 다.우 리 는 결론 을 얻 었 다.
Reference Equals 방법 은 false 를 되 돌려 줍 니 다.같은 대상 의 인용 이 아니 기 때 문 입 니 다.
String 형식의 Equals(string)방법 을 되 돌려 주 는 것 도 true 입 니 다.두 개의 String 유형 이 같 기 때 문 입 니 다(즉,같은 서열 이나 문자).
==연산 자 도 true 로 돌아 갑 니 다.이 두 String 형식의 값 이 같 기 때 문 입 니 다.
가상 방법 Object.Equals 도 true 로 돌아 갑 니 다.이것 은 String 형식 에서 방법 을 다시 썼 기 때 문 입 니 다.String 의 값 이 같은 지 판단 합 니 다.
이제 이 코드 를 수정 해서 String 형식 을 Object 형식 으로 바 꿉 니 다.
 public class Program
 {
   public static void Main(string[] args)
   {
     object str = "Sweet";
     object str = string.Copy((string)str);
     Console.WriteLine(ReferenceEquals(str, str1));
     Console.WriteLine(str.Equals(str1));
     Console.WriteLine(str == str1);
    Console.WriteLine(object.Equals(str, str1));
   }
 } 
 세 번 째 방법 으로 되 돌아 온 결 과 는 수정 전과 일치 하지 않 습 니 다.==연산 자가 되 돌아 온 결 과 는 false 입 니 다.왜 일 까요?
이것 은==연산 자 는 실제 적 으로 정적 인 방법 으로 비 가상 방법 에 대해 컴 파일 할 때 어떤 방법 을 사용 할 것 인 지 를 결정 하기 때문이다.위의 예 에서 인용 형식 은 ceq 명령 을 사용 하고 String 형식 호출 은 정적 op 입 니 다.Equality 방법;이 두 인 스 턴 스 는 같은 대상 의 인용 이 아니 기 때문에 ceq 명령 이 실 행 된 결 과 는 false 입 니 다.
다시 한 번 말씀 드 리 지만=연산 자 와 범 형의 문 제 는 간단 한 방법 을 만 들 고 범 형 방법 을 통 해 두 개의 범 형 매개 변수 가 같 는 지 판단 하고 콘 솔 에 결 과 를 출력 합 니 다.
 static void Equals<T>(T a, T b)
 {
   Console.WriteLine(a == b);
 } 
 위 에 표 시 된 오 류 는 매우 간단 해서=연산 자 를 사용 하여 두 개의 범 형 T 를 비교 할 수 없습니다.T 는 모든 유형 일 수 있 기 때문에 인용 유형,값 유형 일 수 있 고==연산 자의 구체 적 인 실현 을 제공 할 수 없습니다.
아래 와 같이 코드 를 수정 하면:
 static void Equals<T>(T a, T b) where T : class
 {
   Console.WriteLine(a == b);
 }
public class Program
 {
   static void Main(string[] args)
   {
     string str = "Sweet";
     string str1 = string.Copy(str);
     Equals(str, str);
   }
   static void Equals<T>(T a, T b) where T : class
   {
     Console.WriteLine(a == b);
   }
 } 
 결 과 는 당신 이 예상 한 결과 와 다 르 죠?우리 가 기대 하 는 결 과 는 true 이 고 출력 결 과 는 false 입 니 다.그러나 곰 곰 이 생각해 보면 답 을 찾 을 수 있 습 니 다.일반적인 제약 은 인용 유형 이기 때 문 입 니 다.==연산 자 는 인용 유형 에 대해 인용 이 같 기 때문에 IL 코드 는 이 점 을 증명 할 수 있 습 니 다.
 
 만약 에 우리 가 일반적인 방법 중의=연산 자 를 Equals 방법 으로 바 꾸 면 코드 는 다음 과 같 습 니 다.
 static void Equals<T>(T a, T b)
 {
   Console.WriteLine(object.Equals(a, b));
 }그러나 다른 문제 가 생 겼 다.값 유형 에 대해 서 는 포장 이 생 겨 해결 할 방법 이 있 을 까?이 점 에 대하 여 우 리 는 직접 답 을 주 고 시간 이 있 으 면 전문 적 으로 이 문 제 를 토론 할 것 이다.
비교 값 형식 을 IEquatable
 static void Equals<T>(T a, T b)
 {
   Console.WriteLine(EqualityComparer<T>.Default.Equals(a, b));
 }기본 형식==연산 자의 바 텀 메커니즘 은 ceq 명령 을 사용 하여 CPU 레지스터 를 통 해 비교 합 니 다.
참조 형식==연산 자 에 대해 서도 ceq 명령 을 사용 하여 메모리 주 소 를 비교 합 니 다.
과부하===연산 자의 유형 에 대해 서 는 실제로 op 을 호출 합 니 다.equality 라 는 특별한 방법;
가능 한 한==연산 자 리 셋 과 Object.Equals(Object)의 가상 방법 은 같은 결 과 를 되 돌려 줍 니 다.
값 형식 에 대해 Equals 방법 은 기본적으로 모든 필드 를 반사 적 으로 옮 겨 다 니 며 각 필드 의 동일성 을 검사 합 니 다.성능 을 향상 시 키 기 위해 서 는 이 방법 을 다시 써 야 합 니 다.
값 형식 은 기본적으로==연산 자 를 사용 할 수 없습니다.=연산 자의 재 부팅 이 필요 합 니 다.
위 에서 말 한 것 은 편집장 이 여러분 에 게 소개 한 C\#중의=연산 자 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.만약 에 궁금 한 점 이 있 으 면 저 에 게 메 시 지 를 남 겨 주세요.편집장 은 바로 여러분 에 게 답 할 것 입 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
WebView2를 Visual Studio 2017 Express에서 사용할 수 있을 때까지Evergreen .Net Framework SDK 4.8 VisualStudio2017에서 NuGet을 사용하기 때문에 패키지 관리 방법을 packages.config 대신 PackageReference를 사용해야...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.