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);
}
}
위의 예 시 를 실행 하면 두 문장의 결 과 는 모두 true 이다.우 리 는 ildasm.exe 도 구 를 통 해 역 컴 파일 을 하고 IL 코드 를 확인 하 며 바 텀 이 어떻게 실행 되 는 지 알 고 있 습 니 다.만약 에 이전에 IL 명령 을 접 한 적 이 없 지만 괜 찮 습 니 다.여기 서 모든 명령 을 이해 할 필요 가 없습니다.저 희 는 이 두 가지 비교 방식 의 차 이 를 알 고 싶 을 뿐 입 니 다.
이 줄 의 코드 를 볼 수 있 습 니 다:
IL_0008: call instance bool [mscorlib]System.Int32::Equals(int32)
여기 서 int 형식 Equals(Int 32)방법 을 호출 합 니 다.이제 사용==연산 자가 생 성 된 IL 명령 어 를 살 펴 보 겠 습 니 다.
IL_0015: ceq
보 실 수 있 습 니 다.==실행 부 호 는 ceq 명령 을 사용 합 니 다.CPU 레지스터 를 사용 하여 두 값 을 비교 합 니 다.C\#==연산 자 바 텀 체 제 는 equals 방법 을 호출 하 는 것 이 아니 라 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);
}
}
상기 C\#코드 의 IL 코드 는 다음 과 같다.우 리 는 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));
}
}
위의 코드 는 우리 가 이전에 본 것 과 매우 비슷 하지만,이번 에는 String 형식의 변 수 를 사용 합 니 다.우 리 는 문자열 을 만 들 고 s1 변 수 를 지불 합 니 다.다음 줄 코드 에서 이 문자열 의 사본 을 만 들 고 다른 변수 이름 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);
}
}
위의 코드 는 매우 간단 합 니 다.우 리 는=연산 자 를 다시 불 러 옵 니 다.이것 은 정적 방법 입 니 다.그러나 여기 서 주의해 야 할 것 은 방법의 이름 은 perator==이 고 정적 방법 과 유사 성 입 니 다.사실 그것들 은 컴 파 일 러 에서 op 라 는 이름 으로 만들어 진다Equality()의 특수 정적 방법.일 을 더욱 분명하게 하기 위해 서,우 리 는 마이크로소프트 가 실현 한 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);
}
}
위 코드 를 컴 파일 하려 고 시도 할 때 VS 는 다음 과 같은 오 류 를 알려 줍 니 다.오류 알림 에 따라 우 리 는 Person 구조 체 의==연산 자 를 다시 불 러 와 야 합 니 다.다시 불 러 오 는 문 구 는 다음 과 같 습 니 다(구체 적 인 논 리 를 무시 합 니 다).
public static bool operator ==(Person p1, Person p2)
{
}
public static bool operator !=(Person p1, Person p2)
{
}
위 코드 를 추가 한 후 다시 컴 파일 러 를 컴 파일 합 니 다.ildasm.exe 도 구 를 통 해 IL 코드 를 역 컴 파일 하여 보 니 값 형식==연산 자 호출 도 op 입 니 다.Equality 방법.값 유형 에 대해 서 는 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);
}
그러나 이 코드 를 컴 파일 할 때 VS 는 다음 과 같은 오 류 를 알려 줍 니 다.위 에 표 시 된 오 류 는 매우 간단 해서=연산 자 를 사용 하여 두 개의 범 형 T 를 비교 할 수 없습니다.T 는 모든 유형 일 수 있 기 때문에 인용 유형,값 유형 일 수 있 고==연산 자의 구체 적 인 실현 을 제공 할 수 없습니다.
아래 와 같이 코드 를 수정 하면:
static void Equals<T>(T a, T b) where T : class
{
Console.WriteLine(a == b);
}
일반적인 형식 T 를 인용 형식 으로 바 꾸 면 컴 파일 에 성공 할 수 있 습 니 다.Main 방법의 코드 를 수정 하고 같은 String 형식 을 만 듭 니 다.이전 예 와 같 습 니 다.
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));
}
우 리 는 Equals 로 바 꾸 고 class 제약 도 없 앨 수 있 습 니 다.코드 를 다시 실행 하면 콘 솔 인쇄 결과 가 예상 한 것 과 일치 합 니 다.이것 은 호출 이 가상 방법 object.Equals(object)재 작성 후의 실현 이기 때 문 입 니 다.그러나 다른 문제 가 생 겼 다.값 유형 에 대해 서 는 포장 이 생 겨 해결 할 방법 이 있 을 까?이 점 에 대하 여 우 리 는 직접 답 을 주 고 시간 이 있 으 면 전문 적 으로 이 문 제 를 토론 할 것 이다.
비교 값 형식 을 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에 따라 라이센스가 부여됩니다.