演算子のオーバーロード (C# リファレンス)Operator overloading (C# reference)

ユーザー定義型は定義済みの C# 演算子をオーバーロードできます。A user-defined type can overload a predefined C# operator. つまり、1 つまたは両方のオペランドに該当する型では、演算のカスタム実装を提供できます。That is, a type can provide the custom implementation of an operation in case one or both of the operands are of that type. オーバーロード可能な C# 演算子は、「オーバーロード可能な演算子」のセクションで示します。The Overloadable operators section shows which C# operators can be overloaded.

演算子の宣言には operator キーワードを使用します。Use the operator keyword to declare an operator. 演算子の宣言では、次の規則を満たす必要があります。An operator declaration must satisfy the following rules:

  • これには、publicstatic 修飾子の両方が含まれています。It includes both a public and a static modifier.
  • 単項演算子には、1 つの入力パラメーターがあります。A unary operator has one input parameter. 2 項演算子には、2 つの入力パラメーターがあります。A binary operator has two input parameters. どちらの場合も、少なくとも 1 つのパラメーターの型が T または T? でなければなりません。T は演算子の宣言が含まれる型です。In each case, at least one parameter must have type T or T? where T is the type that contains the operator declaration.

次の例は、有理数を表す簡略化された構造を定義しています。The following example defines a simplified structure to represent a rational number. 構造体がいくつかの算術演算子をオーバーロードします。The structure overloads some of the arithmetic operators:

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 への暗黙的な変換を定義することで、前の例を拡張できます。You could extend the preceding example by defining an implicit conversion from int to Fraction. その場合、オーバーロードされた演算子はこれら 2 つの型の引数をサポートします。Then, overloaded operators would support arguments of those two types. つまり、整数を分数に足し、結果として分数を取得できるようになります。That is, it would become possible to add an integer to a fraction and obtain a fraction as a result.

また、operator キーワードを使用してカスタムの型変換を定義することもできます。You also use the operator keyword to define a custom type conversion. 詳細については、「ユーザー定義の変換演算子」 に関するページを参照してください。For more information, see User-defined conversion operators.

オーバーロード可能な演算子Overloadable operators

次の表は、C# 演算子のオーバーロード可/不可に関する情報を示します。The following table provides information about overloadability of C# operators:

演算子Operators オーバーロード可/不可Overloadability
+x-x!x~x++--truefalse+x, -x, !x, ~x, ++, --, true, false これらの単項演算子はオーバーロードできます。These unary operators can be overloaded.
x + yx - yx * yx / yx % yx & yx | yx ^ yx << y, x >> yx == yx != yx < y, x > yx <= y, x >= yx + 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 これらの 2 項演算子はオーバーロードできます。These binary operators can be overloaded. 特定の演算子はペアでオーバーロードする必要があります。詳細については、この表の後にある注を参照してください。Certain operators must be overloaded in pairs; for more information, see the note that follows this table.
x && yx || yx && y, x || y 条件付き論理演算子は、オーバーロードできません。Conditional logical operators cannot be overloaded. ただし、オーバーロードされた true および false 演算子を含む型が特定の方法で & または | もオーバーロードしている場合は、その型のオペランドに対してそれぞれ && または || 演算子の評価が可能になります。However, if a type with the overloaded true and false operators also overloads the & or | operator in a certain way, the && or || operator, respectively, can be evaluated for the operands of that type. 詳細については、「C# 言語仕様」のユーザー定義型条件論理演算子に関するセクションを参照してください。For more information, see the User-defined conditional logical operators section of the C# language specification.
a[i], a?[i]a[i], a?[i] 要素へのアクセスはオーバーロード可能な演算子とは見なされていませんが、インデクサーを定義することができます。Element access is not considered an overloadable operator, but you can define an indexer.
(T)x(T)x キャスト演算子をオーバーロードすることはできませんが、キャスト式で実行できるカスタム型変換を定義することはできます。The cast operator cannot be overloaded, but you can define custom type conversions that can be performed by a cast expression. 詳細については、「ユーザー定義の変換演算子」 に関するページを参照してください。For more information, see User-defined conversion operators.
+=-=*=/=%=&=|=^=<<=, >>=+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= 複合代入演算子を明示的にオーバーロードすることはできません。Compound assignment operators cannot be explicitly overloaded. ただし、二項演算子をオーバーロードするとき、対応する複合代入演算子がある場合は、それも暗黙的にオーバーロードされます。However, when you overload a binary operator, the corresponding compound assignment operator, if any, is also implicitly overloaded. たとえば、+= は、オーバーロード可能な + を使用して評価されます。For example, += is evaluated using +, which can be overloaded.
^xx = yx.yx?.yc ? t : fx ?? yx ??= yx..yx->y=>f(x)asawaitcheckeduncheckeddefaultdelegateisnameofnewsizeofstackallocswitchtypeof^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 これらの演算子はオーバーロードできません。These operators cannot be overloaded.

注意

比較演算子は、ペアでオーバーロードする必要があります。The comparison operators must be overloaded in pairs. つまり、ペアのどちらかの演算子をオーバーロードする場合、もう一方の演算子もオーバーロードする必要があります。That is, if either operator of a pair is overloaded, the other operator must be overloaded as well. 次のようなペアがこれに該当します。Such pairs are as follows:

  • == 演算子と != 演算子== and != operators
  • < 演算子と > 演算子< and > operators
  • <= 演算子と >= 演算子<= and >= operators

C# 言語仕様C# language specification

詳細については、「C# 言語仕様」の次のセクションを参照してください。For more information, see the following sections of the C# language specification:

関連項目See also