Esiste una soluzione alternativa per sovraccaricare l'operatore di assegnazione in C #?

StackOverflow https://stackoverflow.com/questions/292676

  •  08-07-2019
  •  | 
  •  

Domanda

A differenza di C ++, in C # non è possibile sovraccaricare l'operatore di assegnazione.

Sto facendo una classe numerica personalizzata per operazioni aritmetiche con numeri molto grandi e voglio che abbia l'aspetto grafico dei tipi numerici incorporati come int, decimal, ecc. Ho sovraccaricato l'aritmetica operatori, ma il compito rimane ...

Ecco un esempio:

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

Esiste una soluzione alternativa per quel problema?

È stato utile?

Soluzione

Non mi è ancora chiaro che tu ne abbia davvero bisogno. O:

  • Il tuo tipo di numero dovrebbe essere una struttura (che è probabile - i numeri sono l'esempio più comune di strutture). Nota che tutti i tipi con cui vuoi che il tuo tipo si comporti (int, decimale ecc.) Sono strutture.

o

  • Il tipo di numero deve essere immutabile, facendo in modo che ogni operazione di mutazione restituisca una nuova istanza, nel qual caso non è necessario che i dati vengano copiati durante l'assegnazione. (In effetti, il tuo tipo dovrebbe essere immutabile indipendentemente dal fatto che sia una struttura. Le strutture mutabili sono malvagie e un numero certamente non dovrebbe essere un tipo di riferimento mutevole.)

Altri suggerimenti

puoi utilizzare la parola chiave "implicita" per creare un sovraccarico per il compito:

Supponi di avere un tipo come Foo, che ritieni sia implicitamente convertibile da una stringa. Scriveresti il ??seguente metodo statico nella tua classe Foo:

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

Dopo averlo fatto, puoi utilizzare quanto segue nel tuo codice:

Foo x = "whatever";

Non sarai in grado di aggirare il problema con l'aspetto C ++, poiché a = b; ha altra semantica in C ++ rispetto a C #. In C #, a = b; punta allo stesso oggetto come b. In C ++, a = b modifica il contenuto di a. Entrambi hanno i loro alti e bassi. È come te

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

In C ++ (perderà il riferimento al primo oggetto e creerà una perdita di memoria. Ma ignoriamolo qui). Non è nemmeno possibile sovraccaricare l'operatore di assegnazione in C ++.

La soluzione è semplice:

MyType a = new MyType();
MyType b = new MyType();

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

Disclaimer : non sono uno sviluppatore C #

È possibile creare una proprietà di sola scrittura come questa. quindi fare a.Self = b; sopra.

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

Ora, non va bene. Dal momento che viola il principio della minima sorpresa (POLS). Non ci si aspetterebbe che a cambi se si fa a.Self = b;

Invece di creare una copia dei dati quando si passa il riferimento, è possibile rendere immutabile la classe. Quando la classe è immutabile avere più riferimenti ad essa non è un problema poiché non può essere modificata.

Le operazioni che modificano i dati restituirebbero ovviamente nuove istanze.

Un post precedente suggeriva questo:

  

operatore statico implicito pubblico Foo (string normalString) {}

Ho provato questo approccio ... ma per farlo funzionare hai bisogno di questo:

operatore statico implicito pubblico Foo (originale Foo) {}

e il compilatore non ti consentirà di avere una funzione di conversione implicita dal tuo tipo esatto, né da alcun tipo di base di te stesso. Ciò ha senso poiché sarebbe un modo backdoor di sovrascrivere l'operatore di assegnazione, che C # non vuole consentire.

Ecco una soluzione che ha funzionato per me:

public class MyTestClass
{
   private int a;
   private string str;

   public MyTestClass()
   {
      a = 0;
      str = null;
   }

   public MyTestClass(int a, string str)
   {
      this.a = a;
      this.str = str;
   }

   public MyTestClass Clone
   {
      get
      {
         return new MyTestClass(this.a, this.str);
      }
   }
}

Altrove nel codice:

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

Forse ciò che stai cercando può essere risolto utilizzando gli accessori C #.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top