来自MSDN的可重载运算符:
赋值运算符不能重载,但是+=
,例如,可以使用进行重载,赋值运算符可以+
重载。
更重要的是,赋值运算符都无法重载。我认为这是因为垃圾收集和内存管理会产生影响,这是CLR强类型化世界中的潜在安全漏洞。
尽管如此,让我们看看运算符到底是什么。根据著名的杰弗里·里希特(Jeffrey Richter)的书,每种编程语言都有自己的运算符列表,这些运算符列表是通过特殊的方法调用进行编译的,而CLR本身对运算符一无所知。因此,让我们看看到底在+
and +=
运算符后面是什么。
看下面这个简单的代码:
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;
}