주요 산술 연산자와 비교 연산자는 직접 만든 클래스와 구조체에서 사용할 수 있도록 재정의할 수 있어요. 이를 _연산자 오버로딩_이라고 해요.
이 문서에서는 문법은 물론이고 어떤 연산자를 오버로딩할 수 있고 어떤 것은 할 수 없는지도 자세히 다뤄요.
대부분의 연산자는 다음과 같은 형태예요.
static <return type> operaator <operator symbols>(<parameters>);
캐스트 연산자는 다음과 같은 형태예요.
static (explicit|implicit) operator <cast-to-type>(<cast-from-type> <parameter name>);
연산자는 정적 메서드와 같은 방식으로 동작해요.
문법 예시:
struct Point
{
decimal x;
decimal y;
public static bool operator ==(Point pt, Point ptOther)
{
return pt.x == ptOther.x && pt.y == ptOther.y;
}
public static bool operator !=(Point pt, Point ptOther)
{
return !(pt == ptOther);
}
public static Point operator *(Point pt, decimal scale)
{
var ptNew = new Point();
ptNew.x = pt.x * scale;
ptNew.y = pt.y * scale;
return ptNew;
}
public static implicit operator Point((decimal x, decimal y) xy)
{
var pt = new Point();
pt.x = xy.x;
pt.y = xy.y;
return pt;
}
public static explicit operator (decimal x, decimal y)(Point pt)
{
return (pt.x, pt.y);
}
}
Equals() 메서드를 구현하고 == 연산자에서 호출하면 효과를 보는 경우가 많아요. 마찬가지로 비교를 위해서는 IComparable 인터페이스를 구현할 수 있어요. 두 경우 모두 한 번에 두 마리 토끼를 잡는 셈이에요.
표준 연산자 집합에 포함되지 않은 기호로는 연산자를 만들 수 없다는 점을 기억해 두세요. 문서에서 오버로딩할 수 있다고 명시한 연산에 대해서만 기존 기호를 사용할 수 있어요. 오버로딩할 수 있는 연산자는 여기에 나와 있어요.
매개변수의 타입이 다를 때는 순서가 중요하다는 점에 유의하세요. 위 예제 코드에서 pt * 10m은 올바른 식이지만 10m * pt는 컴파일되지 않아요.
연산자 오버로딩 문서에서 문법을 자세히 설명해요.