Existe-t-il une solution de contournement pour surcharger l’opérateur d’affectation en C #?

Contrairement à C ++, en C #, vous ne pouvez pas surcharger l’opérateur d’assignation.

Je fais une classe de nombres personnalisée pour les opérations arithmétiques avec de très grands nombres et je veux qu’elle ait l’aspect des types numériques intégrés tels que int, décimal, etc. J’ai surchargé les opérateurs arithmétiques, mais la mission rest …

Voici un exemple:

Number a = new Number(55); Number b = a; //I want to copy the value, not the reference 

Existe-t-il une solution de contournement à ce problème?

Ce n’est toujours pas clair pour moi que vous avez vraiment besoin de ça. Non plus:

  • Votre type de numéro doit être une structure (ce qui est probable – les nombres sont l’exemple le plus courant de structures). Notez que tous les types que vous voulez que votre type agisse comme (int, décimal, etc.) sont des structures.

ou:

  • Votre type de numéro doit être immuable, chaque opération de mutation renvoyant une nouvelle instance, auquel cas vous n’avez de toute façon pas besoin de copier les données lors de leur affectation. (En fait, votre type devrait être immuable, qu’il s’agisse ou non d’une structure. Les structures mutables sont diaboliques, et un nombre ne devrait certainement pas être un type de référence mutable.)

vous pouvez utiliser le mot clé ‘implicite’ pour créer une surcharge pour l’affectation:

Supposons que vous ayez un type comme Foo, que vous jugez implicitement convertible à partir d’une chaîne. Vous écririez la méthode statique suivante dans votre classe Foo:

 public static implicit operator Foo(ssortingng normalSsortingng) { //write your code here to go from ssortingng to Foo and return the new Foo. } 

Ceci fait, vous pouvez utiliser les éléments suivants dans votre code:

 Foo x = "whatever"; 

Vous ne pourrez pas le contourner avec le look C ++, car a = b; a une autre sémantique en C ++ qu’en C #. En C #, a = b; fait un point sur le même object que b. En C ++, a = b modifie le contenu de a. Les deux ont leurs hauts et leurs bas. C’est comme toi

 MyType * a = new MyType(); MyType * b = new MyType(); a = b; /* only exchange pointers. will not change any content */ 

En C ++ (cela perdra la référence au premier object et créerait une fuite de mémoire. Mais ignorons cela ici). Vous ne pouvez pas surcharger l’opérateur assign en C ++ pour cela non plus.

La solution de contournement est facile:

 MyType a = new MyType(); MyType b = new MyType(); // instead of a = b a.Assign(b); 

Avertissement : je ne suis pas un développeur C #

Vous pouvez créer une propriété en écriture seule, comme celle-ci. alors faites a.Self = b; au dessus de.

 public MyType Self { set { /* copy content of value to this */ this.Assign(value); } } 

Maintenant, ce n’est pas bon. Depuis qu’il viole le principe de la moindre surprise (POLS). On ne s’attendrait pas à un changement si on fait a.Self = b;

Au lieu de copier les données lors de la transmission de la référence, vous pouvez rendre la classe immuable. Lorsque la classe est immuable, avoir plusieurs références à elle n’est pas un problème car elle ne peut pas être modifiée.

Les opérations qui modifient les données renverraient bien sûr de nouvelles instances.

Un post précédent a suggéré ceci:

opérateur implicite statique public Foo (ssortingng normalSsortingng) {}

J’ai essayé cette approche … mais pour que cela fonctionne, vous avez besoin de ceci:

opérateur implicite statique public Foo (Foo original) {}

et le compilateur ne vous laissera pas avoir une fonction de conversion implicite de votre type exact, ni d’aucun type de base de vous-même. Cela a du sens, car c’est une façon détournée de remplacer l’opérateur d’affectation, ce que C # ne veut pas autoriser.

Voici une solution qui a fonctionné pour moi:

 public class MyTestClass { private int a; private ssortingng str; public MyTestClass() { a = 0; str = null; } public MyTestClass(int a, ssortingng str) { this.a = a; this.str = str; } public MyTestClass Clone { get { return new MyTestClass(this.a, this.str); } } } 

Quelque part ailleurs dans le code:

 MyTestClass test1 = new MyTestClass(5, "Cat"); MyTestClass test2 = test1.Clone; 

Peut-être que ce que vous cherchez peut être résolu en utilisant des accesseurs C #.

http://msdn.microsoft.com/en-us/library/aa287786(v=vs.71).aspx