728x90
반응형
1. 참조 타입(reference type)의 동등성(Equality)
using System;
class Point {
private int x = 0;
private int y = 0;
public Point(int xPos, int yPos) {
x = xPos;
y = yPos;
}
}
class Program {
static void Main() {
Point p1 = new Point(1, 1);
Point p2 = p1;
Point p3 = new Point(1, 1);
// 방법1. == 연산자 사용
// 기본 동작 : 참조(주소)가 동일한가 ?
Console.WirteLine(p1 == p2); // true
Console.WriteLine(p1 == p3); // false
// 방법2. Equals() 가상함수 사용
// 기본 동작 : 참조가 동일한가 ?
Console.WriteLine(p1.Equals(p2)); // true
Console.WriteLine(p1.Equals(p3)); // false
}
}
① 객체의 동등성(Equality)를 조사하는 방법
=> == 연산자 사용
=> Equals() 가상 메소드 사용
C#에는 참조타입과 값타입이 구별되니 두 가지를 모두 보아야 한다.
먼저 위의 코드로 참조타입을 먼저 보자.
먼저 위의 코드에서 객체 생성을 그림으로 보면 위와 같다.
이제 코드에서 방법1인 == 연산자를 사용하여 보자.
== 연산자는 기본동작이 참조(주소)가 동일한지를 확인하므로 p1과 p2는 같지만 p3는 다르다고 나온다.
Equals() 함수도 참조가 동일한지 확인하므로 위와 같은 결과값이 나온다.
하지만 코딩을 하다보면 값이 같을 경우에 대한 처리를 하고 싶을 수 있는데 이럴 경우
Equals() 가 가상함수 이므로 재정의 하여 사용하면 된다.
using System;
class Point {
private int x = 0;
private int y = 0;
public Point(int xPos, int yPos) {
x = xPos;
y = yPos;
}
public override bool Equals(object obj) {
Point pt = (Point)obj;
return x == pt.x && y == pt.y;
}
}
class Program {
static void Main() {
Point p1 = new Point(1, 1);
Point p2 = p1;
Point p3 = new Point(1, 1);
// 방법1. == 연산자 사용
// 기본 동작 : 참조(주소)가 동일한가 ?
Console.WirteLine(p1 == p2); // true
Console.WriteLine(p1 == p3); // false
// 방법2. Equals() 가상함수 사용
// 기본 동작 : 참조가 동일한가 ?
Console.WriteLine(p1.Equals(p2)); // true
Console.WriteLine(p1.Equals(p3)); // true
}
}
위와 같이 함수 재정의로 처리 가능하다.
반대로 == 연산자도 연산자 재정의로 처리가 가능하다.
using System;
class Point {
private int x = 0;
private int y = 0;
public Point(int xPos, int yPos) {
x = xPos;
y = yPos;
}
public static bool operator==(Point p1, Point p2) {
return p1.x == p2.x && p1.y == p2.y;
}
public static bool operator!=(Point p1, Point p2) {
return p1.x != p2.x || p1.y != p2.y;
}
}
class Program {
static void Main() {
Point p1 = new Point(1, 1);
Point p2 = p1;
Point p3 = new Point(1, 1);
// 방법1. == 연산자 사용
// 기본 동작 : 참조(주소)가 동일한가 ?
Console.WirteLine(p1 == p2); // true
Console.WriteLine(p1 == p3); // true
// 방법2. Equals() 가상함수 사용
// 기본 동작 : 참조가 동일한가 ?
Console.WriteLine(p1.Equals(p2)); // true
Console.WriteLine(p1.Equals(p3)); // false
}
}
== 연산자와 같이 동등연산자로 만들면 같지 않을 경우인 !=연산자도 만들어야 한다.
② ==연산자
=> 참조(주소)가 동일한가를 조사
=> 연산자 재정의 문법으로 기본 동작 변경 가능. 기반 클래스 타입 참조를 사용할 경우 문제.
③ Equals 가상 메소드
=> 참조(주소)가 동일한가를 조사
=> 재정의 해서 객체의 상태 동일 여부로 구현하는 경우가 많음.
2. 값 타입(value type)의 동등성(Equality)
using System;
struct Point {
private int x = 0;
private int y = 0;
public Point(int xPos, int yPos) {
x = xPos;
y = yPos;
}
}
class Program {
static void Main() {
Point p1 = new Point(1, 1);
Point p2 = p1;
// 방법1. == 연산자 사용
// 기본적으로 제공 안됨. => 연산자 재정의로 사용 가능
Console.WirteLine(p1 == p2); // error
// 방법2. Equals() 가상함수 사용
// 객체에 대한 모든 메모리 조사
Console.WriteLine(p1.Equals(p2)); // true
}
}
이번엔 값 타입의 조사를 하기 위해 class를 struct로 바꾸었다.
먼저 그림으로 보면 아래와 같다.
① == 연산자
=> 제공 되지 않음.
=> 연산자 재정의 문법으로 제공 가능.
using System;
struct Point {
private int x = 0;
private int y = 0;
public Point(int xPos, int yPos) {
x = xPos;
y = yPos;
}
public override bool Equals(Object obj) {
Point pt = (Point)obj;
return x == pt.x
}
}
class Program {
static void Main() {
Point p1 = new Point(1, 1);
Point p2 = p1;
p2.y = 2;
// 비교 정책 변경 - x만 조사하여 같은 경우 true 반환
Console.WriteLine(p1.Equals(p2)); // true
}
}
② Equals 가상 메소드
=> 메모리 내용을 비교
=> 재정의 해서 비교 정책을 변경가능
728x90
반응형
'프로그래밍 > C#' 카테고리의 다른 글
[C#] Elvis Operator (?, ??) 연산자 (0) | 2020.02.06 |
---|---|
[C#] Nullable<T> (0) | 2020.02.04 |
[C#] 값 타입 vs 참조 타입(2) (1) | 2020.01.30 |
[C#] 값 타입과 참조 타입(1) (1) | 2020.01.22 |
[C#] System.Object (0) | 2020.01.21 |