Opérateurs surchargeables , de MSDN:
Les opérateurs d'affectation ne peuvent pas être surchargés, mais +=
, par exemple, sont évalués à l'aide de +
, qui peut être surchargé.
De plus, aucun opérateur d'affectation ne peut être surchargé. Je pense que c'est parce qu'il y aura un effet pour le ramassage des ordures et la gestion de la mémoire, qui est une faille de sécurité potentielle dans le monde à fort typage CLR.
Néanmoins, voyons ce qu'est exactement un opérateur. Selon le célèbre livre de Jeffrey Richter , chaque langage de programmation a sa propre liste d'opérateurs, qui sont compilées dans un appel de méthode spécial, et CLR lui-même ne sait rien des opérateurs. Voyons donc ce qui reste exactement derrière les opérateurs +
et +=
.
Voir ce code simple:
Decimal d = 10M;
d = d + 10M;
Console.WriteLine(d);
Voyons le code IL pour ces 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
Voyons maintenant ce code:
Decimal d1 = 10M;
d1 += 10M;
Console.WriteLine(d1);
Et le code IL pour cela:
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
Ils sont égaux! Ainsi, l' +=
opérateur n'est que du sucre syntaxique pour votre programme en C # , et vous pouvez simplement surcharger l' +
opérateur.
Par exemple:
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;
}
Ce code sera compilé et exécuté avec succès en tant que:
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
Mettre à jour:
Selon votre mise à jour - comme le dit @EricLippert, vous devriez vraiment avoir les vecteurs comme un objet immuable. Le résultat de l'ajout des deux vecteurs est un nouveau vecteur, pas le premier avec des tailles différentes.
Si, pour une raison quelconque, vous devez changer le premier vecteur, vous pouvez utiliser cette surcharge (mais comme pour moi, c'est un comportement très étrange):
public static Vector operator +(Vector left, Vector right)
{
left.x += right.x;
left.y += right.y;
return left;
}