主要な算術演算子と比較演算子は、自作のクラスや構造体で使えるように適応できます。これを 演算子のオーバーロード と呼びます。
この記事では、構文に加えて、どの演算子がオーバーロードできて、どれができないかを詳しく論じています。
ほとんどの演算子は次の形をとります。
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はコンパイルできません。
この演算子のオーバーロードのドキュメントでは、構文の詳細を説明しています。