연산자 오버로딩(C# 참조)

연산자 오버로드(C# 참조)
사용자 정의 형식은 미리 정의된 C# 연산자를 오버로드할 수 있습니다. 즉, 피연산자 중 하나 또는 두 개가 해당 형식인 경우 형식은 작업의 사용자 정의 구현을 제공할 수 있습니다. 오버로드할 수 있는 연산자 섹션에는 오버로드할 수 있는 C# 연산자가 나와 있습니다.
operator 키워드를 사용하여 연산자를 선언합니다. 연산자 선언은 다음 규칙을 충족해야 합니다.
public 및 static 한정자를 모두 포함합니다.
단항 연산자에는 하나의 입력 매개 변수가 있습니다. 이항 연산자에는 두 개의 입력 매개 변수가 있습니다. 각각의 경우 하나 이상의 매개 변수가 T 또는 T? 유형을 가져야 하며, 여기서 T는 연산자 선언이 포함된 유형입니다.
다음 예제에서는 유리수를 나타내는 간단한 구조를 정의합니다. 구조체가 산술 연산자 중 일부를 오버로드합니다.
C#

using System;

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 키워드를 사용하여 사용자 지정 형식 변환을 정의합니다. 자세한 내용은 사용자 정의 변환 연산자를 참조하세요.
오버로드할 수 있는 연산자
다음 표는 C# 연산자의 오버로드 가능성에 대한 정보를 제공합니다.
오버로드할 수 있는 연산자
연산자 오버로드 가능성
+x, -x, !x, ~x, ++, –, true, false 이러한 단항 연산자는 오버로드할 수 있습니다.
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 조건부 논리 연산자는 오버로드할 수 없습니다. 그러나 오버로드된 true 및 false 연산자가 있는 형식도 특정 방식으로 & 또는 | 연산자를 오버로드하는 경우, && 또는 || 연산자는 각각 해당 유형의 피연산자에 대해 평가될 수 있습니다. 자세한 내용은 C# 언어 사양의 사용자 정의 조건부 논리 연산자 섹션을 참조하세요.
a[i], a?[i] 요소 액세스는 오버로드 가능한 연산자로 간주되지 않지만 인덱서를 정의할 수 있습니다.
(T)x 캐스트 연산자는 오버로드될 수 없지만, 캐스트 식에서 수행할 수 있는 사용자 지정 형식 변환을 정의할 수 있습니다. 자세한 내용은 사용자 정의 변환 연산자를 참조하세요.
+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= 복합 할당 연산자를 명시적으로 오버로드할 수 없습니다. 그러나 이항 연산자가 오버로드되면 해당 복합 할당 연산자(있는 경우)도 암시적으로 오버로드됩니다. 예를 들어 +=는 오버로드될 수 있는 +를 사용하여 계산됩니다.
^x, x = y, x.y, x?.y, c ? t : f, x ?? y, x ??= y, x..y, x->y, =>, f(x), as, await, checked, unchecked, default, delegate, is, nameof, new, sizeof, stackalloc, switch, typeof, with 이러한 연산자는 오버로드할 수 없습니다.
참고

비교 연산자는 쌍으로 오버로드되어야 합니다. 즉, 쌍 중 하나의 연산자가 오버로드되면 다른 연산자도 오버로드되어야 합니다. 이러한 쌍은 다음과 같습니다.
== 및 != 연산자
< 및 > 연산자
<= 및 >= 연산자
C# 언어 사양

“연산자 오버로딩(C# 참조)”의 5개의 댓글

답글 남기기