갓똥
나는야 프로그래머
갓똥
전체 방문자
오늘
어제
  • 분류 전체보기 (186)
    • 프로그래밍 (146)
      • 자바 (9)
      • 안드로이드 (2)
      • 유니티 (20)
      • C++ (38)
      • C# (56)
      • HTML (2)
      • 파이썬 (3)
      • 자료구조 (2)
      • 알고리즘 (0)
      • 문제풀이 (4)
      • 디자인 패턴 (7)
      • 카카오톡 봇 (1)
      • 엑셀 (1)
      • 기타 (1)
    • 게임 (21)
      • 테일즈위버 (0)
      • 카이로소프트 (1)
      • 순위 (19)
      • 기타 (1)
    • 일상 (13)
      • 카페 (1)
      • 방탈출 (12)
    • 기타 (6)
      • 웃긴자료 (5)

블로그 메뉴

  • 홈
  • 방명록

공지사항

인기 글

태그

  • 게임매출순위
  • 게임 디자인 패턴
  • 전세계 게임 매출
  • 모바일 게임 순위
  • 유니티 그래프 그리기
  • c# Thread
  • 알고리즘
  • C# boxing
  • 글로벌게임매출
  • 강남 방탈출
  • C++ 소멸자
  • c# coroutine
  • c# unboxing
  • C++
  • c# delegate
  • C# 예외 처리
  • C++ 상속
  • 유니티 그래프
  • c# collection
  • pc게임 순위
  • 전세계게임매출순위
  • C++ virtual
  • 게임 매출 순위
  • 유니티 골드그래프
  • 2020년 게임 매출
  • c# 코루틴
  • pc 게임 순위
  • Unity Graph
  • 롤 골드그래프
  • 자바

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
갓똥

나는야 프로그래머

[C#] 동등성 (Equality)
프로그래밍/C#

[C#] 동등성 (Equality)

2020. 2. 4. 16:03
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
    '프로그래밍/C#' 카테고리의 다른 글
    • [C#] Elvis Operator (?, ??) 연산자
    • [C#] Nullable<T>
    • [C#] 값 타입 vs 참조 타입(2)
    • [C#] 값 타입과 참조 타입(1)
    갓똥
    갓똥
    공부하며 알아가는 내용을 정리해 봅니다.

    티스토리툴바