연산자 오버로딩 - 미리 정의된 단항, 산술, 항등 및 비교 연산자

사용자 정의 형식은 미리 정의된 C# 연산자를 오버로드할 수 있습니다. 즉, 피연산자 중 하나 또는 두 개가 해당 형식인 경우 형식은 작업의 사용자 정의 구현을 제공할 수 있습니다. 오버로드할 수 있는 연산자 섹션에는 오버로드할 수 있는 C# 연산자가 나와 있습니다.

operator 키워드를 사용하여 연산자를 선언합니다. 연산자 선언은 다음 규칙을 충족해야 합니다.

  • publicstatic 한정자를 모두 포함합니다.
  • 단항 연산자에는 하나의 입력 매개 변수가 있습니다. 이항 연산자에는 두 개의 입력 매개 변수가 있습니다. 각각의 경우 하나 이상의 매개 변수가 T 또는 T? 유형을 가져야 하며, 여기서 T는 연산자 선언이 포함된 유형입니다.

다음 예제에서는 유리수를 나타내는 간단한 구조를 정의합니다. 구조체가 산술 연산자 중 일부를 오버로드합니다.

public readonly struct Fraction
{
    private readonly int num;
    private readonly int den;

    public Fraction(int numerator, int denominator)
    {
        if (denominator == 0)
        {
            throw new ArgumentException("Denominator cannot be zero.", nameof(denominator));
        }
        num = numerator;
        den = denominator;
    }

    public static Fraction operator +(Fraction a) => a;
    public static Fraction operator -(Fraction a) => new Fraction(-a.num, a.den);

    public static Fraction operator +(Fraction a, Fraction b)
        => new Fraction(a.num * b.den + b.num * a.den, a.den * b.den);

    public static Fraction operator -(Fraction a, Fraction b)
        => a + (-b);

    public static Fraction operator *(Fraction a, Fraction b)
        => new Fraction(a.num * b.num, a.den * b.den);

    public static Fraction operator /(Fraction a, Fraction b)
    {
        if (b.num == 0)
        {
            throw new DivideByZeroException();
        }
        return new Fraction(a.num * b.den, a.den * b.num);
    }

    public override string ToString() => $"{num} / {den}";
}

public static class OperatorOverloading
{
    public static void Main()
    {
        var a = new Fraction(5, 4);
        var b = new Fraction(1, 2);
        Console.WriteLine(-a);   // output: -5 / 4
        Console.WriteLine(a + b);  // output: 14 / 8
        Console.WriteLine(a - b);  // output: 6 / 8
        Console.WriteLine(a * b);  // output: 5 / 8
        Console.WriteLine(a / b);  // output: 10 / 4
    }
}

암시적 변환int에서 Fraction으로 정의하여 앞의 예제를 확장할 수 있습니다. 그런 다음, 오버로드된 연산자는 해당 두 형식의 인수를 지원합니다. 즉, 분수에 정수를 추가하고 그 결과로 분수를 얻을 수 있습니다.

또한 operator 키워드를 사용하여 사용자 지정 형식 변환을 정의합니다. 자세한 내용은 사용자 정의 변환 연산자를 참조하세요.

오버로드할 수 있는 연산자

다음 표에서는 오버로드할 수 있는 연산자를 보여 줍니다.

연산자 주의
+x, -x, !x, ~x, ++, --, true, false truefalse 연산자는 함께 오버로드되어야 합니다.
x + y, x - y, x * y, x / y, x % y,
x & y, x | y, x ^ y,
x << y, x >> y, x >>> y
x == y, x != y, x < y, x > y, x <= y, x >= y ==!=, <>, <=>= 쌍으로 오버로드되어야 합니다.

오버로드할 수 없는 연산자

다음 표에서는 오버로드할 수 없는 연산자를 보여 줍니다.

연산자 대안
x && y, x || y truefalse 연산자와 & 또는 | 연산자를 모두 오버로드합니다. 자세한 내용은 사용자 정의 조건부 논리 연산자를 참조하세요.
a[i], a?[i] 인덱서를 정의합니다.
(T)x 캐스트 식으로 수행할 수 있는 사용자 지정 형식 변환을 정의합니다. 자세한 내용은 사용자 정의 변환 연산자를 참조하세요.
+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=, >>>= 해당 이진 연산자를 오버로드합니다. 예를 들어, 이항 + 연산자를 오버로드하면 +=가 암시적으로 오버로드됩니다.
^x, x = y, x.y, x?.y, c ? t : f, x ?? y, ??= y,
x..y, x->y, =>, f(x), as, await, checked, unchecked, default, delegate, is, nameof, new,
sizeof, stackalloc, switch, typeof, with
없음.

C# 언어 사양

자세한 내용은 C# 언어 사양의 다음 섹션을 참조하세요.

참고 항목