问题描述
我试图做运算符重载的+ =,但我不能。我只能让一个运算符重载为+。
I am trying to do operator overloads for "+=", but I can't. I can only make an operator overload for "+".
为什么?
修改
这是不工作的原因是,我有一个Vector类(用X和Y字段)。考虑下面的例子。
The reason this is not working is that I have a Vector class (with an X and Y field). Consider the following example.
vector1 += vector2;
如果我的运算符重载设置为:
If my operator overload is set to:
public static Vector operator +(Vector left, Vector right)
{
return new Vector(right.x + left.x, right.y + left.y);
}
那么结果将不会被添加到向量1,而是,向量1将成为一个全新的矢量参考为好。
Then the result won't be added to vector1, but instead, vector1 will become a brand new Vector by reference as well.
推荐答案
重载操作,从MSDN:
赋值运算符不能重载,但 + =
,例如,在使用评估 +
,它可以是超载。
更,没有赋值操作符可以被重载。我认为这是因为将有垃圾收集和内存管理,这是CLR强类型的世界潜在的安全漏洞的影响。
Even more, none of assignment operators can be overloaded. I think this is because there will be an effect for the Garbage collection and memory management, which is a potential security hole in CLR strong typed world.
不过,让我们来看看究竟运营商是。根据著名杰弗里里希特的书,每种编程语言都有自己的运营商名单,这是在一个特殊的方法编译电话,和CLR本身并不知道经营什么。所以,让我们来看看究竟留下的 +
和 + =
运营商。
Nevertheless, let's see what exactly an operator is. According to the famous Jeffrey Richter's book, each programming language has its own operators list, which are compiled in a special method calls, and CLR itself doesn't know anything about operators. So let's see what exactly stays behind the +
and +=
operators.
请参阅这个简单的code:
See this simple code:
Decimal d = 10M;
d = d + 10M;
Console.WriteLine(d);
让查看IL-code这说明:
Let view the IL-code for this instructions:
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
现在让我们看看这个code:
Now lets see this code:
Decimal d1 = 10M;
d1 += 10M;
Console.WriteLine(d1);
和IL-$ C $下这样的:
And IL-code for this:
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#,然后你可以简单地重载 +
运营商。
They are equal! So the +=
operator is just syntactic sugar for your program in C#, and you can simply overload +
operator.
例如:
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;
}
这code会被编译并成功运行为:
This code will be compiled and successfully run as:
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说,你真的应该有向量作为不可变对象。两个向量的加入结果是一个新载体,不是第一个具有不同的尺寸。
According to your Update - as the @EricLippert says, you really should have the vectors as an immutable object. Result of adding of the two vectors is a new vector, not the first one with different sizes.
如果由于某种原因你需要改变第一个向量,就可以使用此重载(但对我来说,这是非常奇怪的行为):
If, for some reason you need to change first vector, you can use this overload (but as for me, this is very strange behaviour):
public static Vector operator +(Vector left, Vector right)
{
left.x += right.x;
left.y += right.y;
return left;
}
这篇关于C#运算符重载的" + ="?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!