안녕하세요 삽잡이입니다.
이번 시간은 연산자 오버로딩에 대해서 알아보려고합니다.
C++을 배우셨던 분들이라면 분명 익숙하게 들릴 만한 주제라고 생각합니다.
연산자 오버로딩을 하는 이유는
연산자가 정의되어있지 않은 형식 즉, 사용자 형식(클래스형식)에 대해서
내장 되어있는 연산자가 동작하도록 하기 위해서 입니다.
그 결과로 더 쉽게 사용할 수 있고, 명확한 코드를 만들 수 있게 되지요.
C++과 다르게 C#에서 연산자 중복을 할 때에는
멤버 함수,전역 함수로 오버로딩을 하지 못합니다.
왜냐하면 전역함수가 C#에서는 없기 때문입니다. 따라서 static 메서드를 사용하게 됩니다.
그래서 이항 연산자 오버로딩을 할 때에는 인자를 기본적으로 두개를 받게됩니다.
C#에서는 전역 함수 연산자 중복만을 제공해줍니다.
즉, 전역 함수라는 것이 없기 때문에 이를 static으로 제공해준다는 소리입니다.
사실, C#에서 자주 사용하는 연산자로써는
' +, -, +=, -=, ==, != ' 이와 같은 6개의 연산자만을 사용합니다.
뭐... 신기하게도 .NET에서는 알아서 전위 후위 연산을 변환해주는 편리성도 제공해줍니다.
C++에서는 다 따로 따로 만들었어야했지요.
그런데, 등가 연산자는 좀 알아둘 필요가 있습니다.
==, != 라는 등가 연산자에 대한 연산자 중복이 나름 중요하다는 소리입니다.
우리가 예전에 배웠던 object에 있는 메서드들입니다.
이때 equals 메서드에 대해서 주목해주시길 바랍니다.
virtual에 있는 Equals 메서드는 object형 인수를 받습니다.
그리고 이 메서드는 자신과 상대를 비교하는 기능을 가지고 있지요.
그런데, 이 equals 메서드는 다른 곳에서도 존재합니다.
바로 object가 제공하는 static 메서드에 존재하지요.
모든 equals 메서드의 return 형은 bool 형식입니다.
static 메서드의 두 equals 메서드 중
ReferenceEquals() 메서드는 참조만을 비교하는 메서드입니다.
두 정적 메서드는 virtual Equals() 메서드를 일반적으로 오버라이딩하여 사용하게 되지요.
static Equals() 메서드는 내부적으로 virtual Equals()메서드를 호출한다고 했었습니다.
그리고 ReferenceEquals() 메서드는 오버라이드를 하게 되더라도
참조가 같은지, 같은 객체인지를 묻게 됨으로 객체의 값이 같은지는 물어보지 않습니다.
그런데, 오버라이드를 하지 않게 되면 단지 모두 똑같은 virtual Equals() 메서드가 될 뿐입니다.
즉, 기본적으로는 객체가 같은지만 물어본다는 것입니다.
그런데 ==, != 연산자 중복을 하다가 왜 이렇게 흘러갔느냐?
== 연산자도 Equals() 메서드와 똑같기 때문입니다.
== 연산자를 연산자 오버로딩을 하게 되었을 때
virtual Equals() 메서드에 대해서 정의를 해줘야한다는 것입니다.
Equals() 메서드를 호출했는데, == 연산자와 달라지면 의미가 없지 않겠습니까?
Equals()나 == 나 똑같은 의미인데 당연한 소리지요.
따라서 == 연산자 중복을 할 때에는
따로 독립적으로 구분하는 것이 아니라, virtual Equals() 메서드를 이용해서 만들어야합니다.
즉, == 연산자를 따로 구현하면 안된다는 것입니다.
반드시 virtual Equals() 메서드를 활용해야한다는 사실을 잊지 마시길 바랍니다.
static의 Equals() 메서드들도 virtual Eqauls() 메서드를 활용해서 사용합니다.
그래야 Equals() 메서드들이 모두 다 동일하게 돌아가지 않겠습니까?
그래서 구현은 virtaul Equals()에서 하고
다른 Equals() 메서드들을 모두 vriaul Eqauls() 를 불러다가 쓰도록 해야합니다.
또한, 기본적으로 C#에서 ==, != 연산자는 쌍으로 만들어줘야합니다.
아니면 컴파일러가 warning을 때립니다.
그런데 이렇게 쌍으로 붙어다녀야 하는 연산자가 하나 더 있습니다.
바로 '비교 연산자 오버로딩'입니다.
이 연산자들도 독립적으로 만들면 안됩니다.
비교라는 기능이기 때문에 'IComparable' 인터페이스가 반드시 따라다녀야합니다.
IComparable 인터페이스를 구현한 객체는
해당 객체가 비교 가능한 객체임을 명시하게 됩니다.
따라서 해당 인터페이스를 구현하지 않는다면 비교가 되지 않겠지요.
Virtual Equals() 메서드와 ==, != 연산자가 쌍이라면,
>, >=, <, <= 연산자 모두 IComparable 인터페이스와 쌍이라는 사실을 기억하시길 바랍니다.
모두 1차적으로 Virtual Equals(), IComparable 을 만들어주고
연산자는 이 녀석들을 활용해서 만들어야하는 것입니다.
그래야 의미가 같아지기 때문입니다.
그리고 사실, 각 연산자들은 컴파일러가 내부적으로 메서드를 만들어줍니다.
즉, 연산자는 존재하지 않고, 단지 함수가 존재할 뿐인 것입니다.
이번 시간은 여기까지 알아보도록 하겠습니다.
이상 삽잡이였습니다!
<참고 : C# and the .NET4 Platform>
'삽질의 현장 > - .NET' 카테고리의 다른 글
#061_닷넷(.NET)_.Net Framework 기본 - 확장 메서드 (0) | 2015.11.05 |
---|---|
#060_닷넷(.NET)_.Net Framework 기본 - 사용자 정의 타입 변환 (0) | 2015.11.05 |
#058_닷넷(.NET)_.Net Framework 기본 - 인덱서 메서드 (0) | 2015.11.05 |
[삽잡이::C#] Split 메서드 (0) | 2015.11.05 |
#057_닷넷(.NET)_.Net Framework 기본 - 대리자 & 이벤트 & 람다 정리 (0) | 2015.11.04 |