オーバーロード可能な演算子、MSDNから:
代入演算子はオーバーロードできませんが+=
、たとえば、は+
オーバーロードできるを使用して評価されます。
さらに、どの代入演算子もオーバーロードできません。これは、ガベージコレクションとメモリ管理に影響が出るためだと思います。これは、CLRの強い型指定の世界で潜在的なセキュリティホールになります。
それでも、演算子とは何かを見てみましょう。有名なJeffrey Richterの本によると、各プログラミング言語には独自の演算子リストがあり、特別なメソッド呼び出しでコンパイルされており、CLR自体は演算子について何も知りません。では+
、+=
演算子と演算子の後ろに何が残っているかを見てみましょう。
次の簡単なコードをご覧ください。
Decimal d = 10M;
d = d + 10M;
Console.WriteLine(d);
この手順のILコードを見てみましょう。
IL_0000: nop
IL_0001: ldc.i4.s 10
IL_0003: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
IL_0008: stloc.0
IL_0009: ldloc.0
IL_000a: ldc.i4.s 10
IL_000c: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
IL_0011: call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Addition(valuetype [mscorlib]System.Decimal,
valuetype [mscorlib]System.Decimal)
IL_0016: stloc.0
このコードを見てみましょう:
Decimal d1 = 10M;
d1 += 10M;
Console.WriteLine(d1);
そしてこれのためのILコード:
IL_0000: nop
IL_0001: ldc.i4.s 10
IL_0003: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
IL_0008: stloc.0
IL_0009: ldloc.0
IL_000a: ldc.i4.s 10
IL_000c: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
IL_0011: call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Addition(valuetype [mscorlib]System.Decimal,
valuetype [mscorlib]System.Decimal)
IL_0016: stloc.0
彼らは等しいです!したがって、+=
演算子はC#でのプログラムの単なる構文上の砂糖であり、+
演算子を単純にオーバーロードできます。
例えば:
class Foo
{
private int c1;
public Foo(int c11)
{
c1 = c11;
}
public static Foo operator +(Foo c1, Foo x)
{
return new Foo(c1.c1 + x.c1);
}
}
static void Main(string[] args)
{
Foo d1 = new Foo (10);
Foo d2 = new Foo(11);
d2 += d1;
}
このコードはコンパイルされ、次のように正常に実行されます。
IL_0000: nop
IL_0001: ldc.i4.s 10
IL_0003: newobj instance void ConsoleApplication2.Program/Foo::.ctor(int32)
IL_0008: stloc.0
IL_0009: ldc.i4.s 11
IL_000b: newobj instance void ConsoleApplication2.Program/Foo::.ctor(int32)
IL_0010: stloc.1
IL_0011: ldloc.1
IL_0012: ldloc.0
IL_0013: call class ConsoleApplication2.Program/Foo ConsoleApplication2.Program/Foo::op_Addition(class ConsoleApplication2.Program/Foo,
class ConsoleApplication2.Program/Foo)
IL_0018: stloc.1
更新:
あなたのアップデートによると-@EricLippertが言うように、あなたは本当に不変のオブジェクトとしてベクトルを持つべきです。2つのベクトルを追加した結果は、サイズの異なる最初のベクトルではなく、新しいベクトルです。
何らかの理由で最初のベクトルを変更する必要がある場合は、このオーバーロードを使用できます(ただし、私にとっては、これは非常に奇妙な動作です)。
public static Vector operator +(Vector left, Vector right)
{
left.x += right.x;
left.y += right.y;
return left;
}