J'essaie de faire des surcharges d'opérateurs pour +=
, mais je ne peux pas. Je ne peux faire une surcharge d'opérateur que pour +
.
Comment venir?
Éditer
La raison pour laquelle cela ne fonctionne pas est que j'ai une classe Vector (avec un champ X et Y). Prenons l'exemple suivant.
vector1 += vector2;
Si ma surcharge d'opérateur est définie sur:
public static Vector operator +(Vector left, Vector right)
{
return new Vector(right.x + left.x, right.y + left.y);
}
Ensuite, le résultat ne sera pas ajouté à vector1, mais à la place, vector1 deviendra également un tout nouveau vecteur par référence.
Réponses:
Opérateurs surchargeables , de MSDN:
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:
Voyons le code IL pour ces instructions:
Voyons maintenant ce code:
Et le code IL pour cela:
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:
Ce code sera compilé et exécuté avec succès en tant que:
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):
la source
v3 = v1 + v2;
entraînev1
un changement etv3
est inhabituelJe pense que vous trouverez ce lien informatif: les opérateurs surchargeables
la source
C'est pour la même raison que l'opérateur d'affectation ne peut pas être surchargé. Vous ne pouvez pas écrire de code qui effectuerait correctement l'affectation.
De MSDN .
la source
Vous ne pouvez pas surcharger
+=
car ce n'est pas vraiment un opérateur unique, c'est juste du sucre syntaxique .x += y
est juste une manière abrégée d'écrirex = x + y
. Comme il+=
est défini en termes d' opérateurs+
et=
, vous permettre de le remplacer séparément pourrait créer des problèmes, dans les cas oùx += y
etx = x + y
ne se comporterait pas exactement de la même manière.À un niveau inférieur, il est très probable que le compilateur C # compile les deux expressions dans le même bytecode, ce qui signifie qu'il est très probable que le runtime ne puisse pas les traiter différemment pendant l'exécution du programme.
Je peux comprendre que vous souhaitiez peut-être le traiter comme une opération séparée: dans une instruction comme
x += 10
vous savez que vous pouvez muter l'x
objet sur place et peut-être économiser du temps / de la mémoire, plutôt que de créer un nouvel objetx + 10
avant de l'assigner sur l'ancienne référence .Mais considérez ce code:
Devrait
a == b
à la fin? Pour la plupart des types, non,a
c'est 10 de plus queb
. Mais si vous pouviez surcharger l'+=
opérateur pour qu'il mute sur place, alors oui. Maintenant, considérez celaa
etb
pourrait être transmis à des parties éloignées du programme. Votre éventuelle optimisation pourrait créer des bogues déroutants si votre objet commence à changer là où le code ne l'attend pas.En d'autres termes, si les performances sont si importantes, ce n'est pas trop difficile à remplacer
x += 10
par un appel de méthode commex.increaseBy(10)
, et c'est beaucoup plus clair pour toutes les personnes impliquées.la source
it's just syntactic sugar
enit's just syntactic sugar in C#
; sinon, cela semble trop général, mais dans certains langages de programmation, ce n'est pas seulement du sucre syntaxique, mais peut en fait offrir des avantages en termes de performances.+=
pourrait probablement être optimisé par un compilateur intelligent, car l'arithmétique est simple. Mais une fois que vous avez affaire à des objets, tous les paris sont ouverts. Toute langue est confrontée à peu près aux mêmes problèmes. C'est pourquoi la surcharge des opérateurs est un mal.C'est parce que cet opérateur ne peut pas être surchargé:
MSDN
Surcharger simplement l'
+
opérateur, à cause dex += y
égal àx = x + y
la source
La surcharge de l'opérateur pour
+
est utilisée dans l'+=
opérateur,A += B
égale àA = operator+(A, B)
.la source
Si vous surchargez l'
+
opérateur comme ceci:tu peux faire
ou
Cela compilera et fonctionnera de la même manière.
la source
Il y a toujours la même réponse à ce problème: pourquoi avez-vous besoin du
+=
, si vous l'obtenez gratuitement si vous surchargez le fichier+
. Mais que se passe-t-il si j'ai une classe comme celle-ci.Dites-vous toujours qu'il est bon que le
+=
soit "implémenté automatiquement". Si vous essayez de faire du calcul haute performance en C #, vous devez avoir de telles fonctionnalités pour réduire le temps de traitement et la consommation de mémoire, si quelqu'un a une bonne solution, c'est très apprécié, mais ne me dites pas que je dois le faire avec des méthodes statiques , ce n'est qu'une solution de contournement et je ne vois aucune raison pour laquelle C # fait l'+=
implémentation s'il n'est pas défini, et s'il est défini, il sera utilisé. Certaines personnes disent que ne pas avoir de différence entre+
et+=
empêche les erreurs, mais n'est-ce pas mon propre problème?la source
+=
est votre propre problème ... ce n'est vrai que si personne d'autre n'a jamais à lire, maintenir ou exécuter votre code.List<T>
utilisant un opérateur commelist += "new item"
, par exemple. Vous appelez saAdd
méthode à la place.J'ai eu exactement la même question et je ne peux pas y répondre mieux que cette personne a
la source
Une meilleure méthode de conception est le casting explicite. Vous pouvez certainement surcharger Casting.
la source