ตัวดำเนินการที่โอเวอร์โหลดจาก 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 กล่าวคุณควรมีเวกเตอร์เป็นวัตถุที่ไม่เปลี่ยนรูป ผลของการเพิ่มเวกเตอร์ทั้งสองเป็นเวกเตอร์ใหม่ไม่ใช่เวกเตอร์แรกที่มีขนาดต่างกัน
หากคุณต้องเปลี่ยนเวกเตอร์แรกด้วยเหตุผลบางประการคุณสามารถใช้โอเวอร์โหลดนี้ได้ (แต่สำหรับฉันนี่เป็นพฤติกรรมที่แปลกมาก):
public static Vector operator +(Vector left, Vector right)
{
left.x += right.x;
left.y += right.y;
return left;
}