演算子のオーバーロード - 定義済みの単項演算子、算術演算子、等値演算子、および比較演算子
ユーザー定義型は定義済みの C# 演算子をオーバーロードできます。 つまり、1 つまたは両方のオペランドに該当する型では、演算のカスタム実装を提供できます。 オーバーロード可能な C# 演算子は、「オーバーロード可能な演算子」のセクションで示します。
演算子の宣言には operator
キーワードを使用します。 演算子の宣言では、次の規則を満たす必要があります。
- これには、
public
とstatic
修飾子の両方が含まれています。 - 単項演算子には、1 つの入力パラメーターがあります。 2 項演算子には、2 つの入力パラメーターがあります。 どちらの場合も、少なくとも 1 つのパラメーターの型が
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
への暗黙的な変換を定義することで、前の例を拡張できます。 その場合、オーバーロードされた演算子はこれら 2 つの型の引数をサポートします。 つまり、整数を分数に足し、結果として分数を取得できるようになります。
また、operator
キーワードを使用してカスタムの型変換を定義することもできます。 詳細については、「ユーザー定義の変換演算子」 に関するページを参照してください。
オーバーロード可能な演算子
次の表は、オーバーロードできる演算子の一覧です:
演算子 | メモ |
---|---|
+x , -x , !x , ~x , ++ , -- , true , false |
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 、x || y |
true 演算子と false 演算子の両方と & 演算子または | 演算子をオーバーロードします。 詳細については、「ユーザー定義の条件付き論理演算子」を参照してください。 |
a[i] 、a?[i] |
インデクサーを定義します。 |
(T)x |
キャスト式で実行できるカスタム型変換を定義します。 詳細については、「ユーザー定義の変換演算子」 に関するページを参照してください。 |
+= , -= , *= , /= , %= , &= , |= , ^= , <<= , >>= , >>>= |
対応する 2 項演算子をオーバーロードします。 たとえば、二項演算子 + をオーバーロードすると、 += は暗黙的にオーバーロードされます。 |
^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# 言語仕様」の次のセクションを参照してください。
関連項目
GitHub で Microsoft と共同作業する
このコンテンツのソースは GitHub にあります。そこで、issue や pull request を作成および確認することもできます。 詳細については、共同作成者ガイドを参照してください。
.NET