Các nhà khai thác quá tải , từ MSDN:
Các toán tử gán không thể được nạp chồng, nhưng +=
ví dụ, được đánh giá bằng cách sử dụng +
, có thể được nạp chồng.
Thậm chí, không có toán tử gán nào có thể bị quá tải. Tôi nghĩ điều này là do sẽ có ảnh hưởng đến việc thu thập Rác và quản lý bộ nhớ, đây là một lỗ hổng bảo mật tiềm ẩn trong thế giới được đánh máy mạnh mẽ của CLR.
Tuy nhiên, hãy xem toán tử chính xác là gì. Theo cuốn sách nổi tiếng của Jeffrey Richter , mỗi ngôn ngữ lập trình đều có danh sách toán tử riêng, được biên dịch theo các lệnh gọi phương thức đặc biệt, và bản thân CLR không biết gì về toán tử. Vì vậy, chúng ta hãy xem những gì chính xác nằm sau toán tử +
và +=
.
Xem mã đơn giản này:
Decimal d = 10M;
d = d + 10M;
Console.WriteLine(d);
Hãy xem mã IL để biết hướng dẫn này:
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
Bây giờ chúng ta hãy xem mã này:
Decimal d1 = 10M;
d1 += 10M;
Console.WriteLine(d1);
Và mã IL cho điều này:
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
Họ đều bình đẳng! Vì vậy, +=
toán tử chỉ là đường cú pháp cho chương trình của bạn trong C # , và bạn có thể nạp chồng +
toán tử một cách đơn giản .
Ví dụ:
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;
}
Mã này sẽ được biên dịch và chạy thành công dưới dạng:
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
Cập nhật:
Theo Bản cập nhật của bạn - như @EricLippert nói, bạn thực sự nên có các vectơ như một đối tượng bất biến. Kết quả của việc thêm hai vectơ là một vectơ mới , không phải là vectơ đầu tiên có kích thước khác nhau.
Nếu vì lý do nào đó mà bạn cần thay đổi vectơ đầu tiên, bạn có thể sử dụng quá tải này (nhưng đối với tôi, đây là hành vi rất lạ):
public static Vector operator +(Vector left, Vector right)
{
left.x += right.x;
left.y += right.y;
return left;
}