Frage

Im Gegensatz zu C ++, C # können Sie nicht den Zuweisungsoperator überlasten.

Ich mache eine benutzerdefinierte Anzahl Klasse für arithmetische Operationen mit sehr großen Zahlen, und ich will es das Look-and-Feel der integrierten in numerische Typen wie int haben, dezimal, usw. Ich habe das arithmetische überlastet Betreiber, aber die Zuordnung bleibt ...

Hier ist ein Beispiel:

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

Gibt es eine Abhilfe für dieses Problem?

War es hilfreich?

Lösung

Es ist immer noch nicht klar für mich, dass Sie das wirklich brauchen. Entweder:

  • Ihre Nummer Typ sollte eine Struktur sein (was wahrscheinlich ist - Zahlen sind das häufigste Beispiel für structs). Beachten Sie, dass alle Typen, die Sie Ihren Typ wie (int, dezimal usw.) handeln wollen, sind structs.

oder:

  • Sie sollte Nummer Typ unveränderlich sein, jede Mutationsoperation eine neue Instanz zurückkehren zu machen, in dem Fall, dass Sie die Daten nicht mehr benötigen ohnehin auf Zuweisung kopiert werden. (In der Tat soll Ihre Art unveränderlich sein, ob oder nicht, es ist eine Struktur. Mutable structs sind böse, und eine Reihe sicherlich nicht ein veränderliches Referenztyp sein.)

Andere Tipps

können Sie das ‚implizite‘ Schlüsselwort verwenden, um eine Überlastung für die Zuordnung zu erstellen:

Angenommen, Sie einen Typ wie Foo haben, dass Sie das Gefühl, aus einer Zeichenfolge implizit konvertierbar ist. Sie würden die folgende statische Methode in der Klasse Foo schreiben:

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

Nachdem das getan, können Sie dann den folgenden in Ihrem Code verwenden:

Foo x = "whatever";

Sie werden nicht in der Lage sein, um es zu arbeiten, die C ++ aussehen, da a = b; hat andere Semantik in C ++ als in C #. In C #, a = b; macht einen Punkt auf das gleiche Objekt wie b. In C ++, a = b ändert sich der Inhalt eines. Beide haben ihre Höhen und Tiefen. Es ist wie Sie tun

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

In C ++ (es wird die Bezugnahme auf das erste Objekt verlieren, und ein Speicherleck schaffen. Aber sie ignoriert, dass hier). Sie können nicht den assign Operator in C ++ überladen für das auch nicht.

Die Abhilfe ist einfach:

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

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

Hinweis : Ich bin kein C # -Entwickler

Sie können einen Schreib only-Eigenschaft wie folgt erstellen. dann tun a.Self = b; oben.

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

Nun, dies ist nicht gut. Da gegen den Grundsatz-of-Least-Überraschung (POL). Man würde nicht erwarten, dass ein sich ändern, wenn man a.Self = b tut;

Anstatt eine Kopie der Daten zu machen, wenn die Referenz Passieren Sie könnten die Klasse unveränderlich machen. Wenn die Klasse ist unveränderlich mehrere Referenzen, die es kein Problem ist, da es nicht geändert werden kann.

Operationen, die die Daten verändert würde natürlich neue Instanzen zurück.

Eine frühere Post vorgeschlagen folgt aus:

  

public static impliziter Operator Foo (string normalString) {}

habe ich versucht, diesen Ansatz ... aber es Sie diese brauchen funktioniert:

public static impliziter Operator Foo (Foo Original) {}

und der Compiler wird nicht zulassen, Sie haben eine implizite Konvertierungsfunktion von Ihrem genauen Typ, noch von irgendeine Basistyp selbst. Das macht Sinn, da es ein Backdoor-Weg von Überschreiben des Zuweisungsoperators wäre, die C # nicht erlauben wollen.

Hier ist eine Lösung, die für mich gearbeitet:

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);
      }
   }
}

Irgendwo anders im Code:

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

Vielleicht, was Sie suchen können mit C # Accessoren gelöst werden.

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top