MSDN'den Aşırı Yüklenebilir Operatörler :
Atama operatörleri aşırı yüklenemez, ancak +=
örneğin, +
aşırı yüklenebilen kullanılarak değerlendirilir .
Dahası, atama operatörlerinin hiçbiri aşırı yüklenemez. Bunun CLR güçlü tip dünyasında potansiyel bir güvenlik açığı olan Çöp toplama ve bellek yönetimi için bir etki olacağını düşünüyorum.
Yine de, bir operatörün tam olarak ne olduğunu görelim. Ünlü Jeffrey Richter'in kitabına göre , her programlama dilinin özel bir yöntem çağrılarında derlenen kendi operatör listesi vardır ve CLR'nin kendisi operatörler hakkında hiçbir şey bilmiyor. Öyleyse +
ve +=
operatörlerinin arkasında tam olarak neyin kaldığını görelim .
Bu basit koda bakın:
Decimal d = 10M;
d = d + 10M;
Console.WriteLine(d);
Bu talimatlar için IL kodunu inceleyelim:
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
Şimdi bu kodu görelim:
Decimal d1 = 10M;
d1 += 10M;
Console.WriteLine(d1);
Ve bunun için IL kodu:
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
Onlar eşit! Yani +=
operatör, C # programınız için sadece sözdizimsel şekerdir ve +
operatörü basitçe aşırı yükleyebilirsiniz .
Örneğin:
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;
}
Bu kod şu şekilde derlenecek ve başarıyla çalıştırılacaktır:
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
Güncelleme:
Güncellemenize göre - @EricLippert'in dediği gibi, vektörlere gerçekten değişmez bir nesne olarak sahip olmalısınız. İki vektörün eklenmesinin sonucu, farklı boyutlara sahip ilki değil, yeni bir vektördür.
Herhangi bir nedenle ilk vektörü değiştirmeniz gerekirse, bu aşırı yüklemeyi kullanabilirsiniz (ama bana gelince, bu çok garip bir davranış):
public static Vector operator +(Vector left, Vector right)
{
left.x += right.x;
left.y += right.y;
return left;
}