5 Stimmen

c# = Operator-Problem

In C# habe ich eine einfache 3D-Vektorklasse.

static void Main(string[] args)
{
    Vector3D a, b;
    a = new Vector3D(0, 5, 10);
    b = new Vector3D(0, 0, 0);

    b = a;
    a.x = 10;

    Console.WriteLine("vector a=" + a.ToString());
    Console.WriteLine("vector b=" + b.ToString());
    Console.ReadKey();
}

ist die Ausgabe,

Vektor a= 10, 5, 10

Vektor b= 10, 5, 10

Ich weise a zu, bevor ich a.x auf 10 ändere. Ich hatte also erwartet

Vektor a= 10, 5, 10

Vektor b= 0, 5, 10

Von was ich verstehe = Operator weist einen Verweis auf Objekt wie ein Zeiger? Und in C# kann ich nicht überladen = Operator.

Muss ich jede Eigenschaft manuell zuweisen?

10voto

Henk Holterman Punkte 249753

Ja, denn Vecor3D ist ein Klasse Das ist ganz richtig.

Klassen sind Referenztypen und Ihre b = a; Anweisung kopiert nicht eine Vector3D-Instanz, sondern einen Verweis auf eine Instanz.

Wenn Sie die Instanzen "klonen" wollen, könnten Sie die IClonable-Schnittstelle hinzufügen, aber das ist mehr oder weniger aufgegeben.

Eine bessere Lösung für eine <X,Y,Z> Typs könnte sein, ihn zu einer Struktur zu machen. Structs sind Wertetypen und die Bedeutung von b = a; ändern würde (in Richtung dessen, was Sie wollen).

Ein 3D-Punkt erfüllt alle Kriterien für eine Struktur (klein, keine Identität). Der bevorzugte Weg ist, ihn als unveränderlich zu gestalten.

2voto

AllenG Punkte 8032

Möglicherweise möchten Sie Ihre Vector3D Klasse zu einer Struktur. Dadurch können Sie mit einem Werttyp anstelle eines Referenztyps arbeiten.

Die andere Möglichkeit ist die Implementierung ICloneable oder verwenden Sie eine andere Methode zur Erstellung einer tiefen Kopie Ihres Objekts.

2voto

Heinzi Punkte 157917

Ja, " \= Operator ordnet einen Verweis auf ein Objekt wie einen Zeiger zu ", wie Sie es ausdrücken. Somit sind beide a y b die gleiche Referenz einzeln Objekt im Speicher. (Das Objekt, auf das zuvor durch b wird nicht mehr referenziert und wird in den Müll geworfen).

Es gibt mehrere Möglichkeiten, dieses Problem zu lösen:

  1. Machen Sie Vector3D a Struktur anstelle einer Klasse. Strukturen sind Wert Typen anstelle von Referenztypen, so dass b = a Kopien den Inhalt von a zu variabel b .

  2. Umsetzung einer Clone Methode in Ihrem Vector3D Klasse (früher bedeutete dies die Implementierung von ICloneable aber dies wird nicht mehr empfohlen ). Alternativ können Sie auch eine Vector3D Konstruktor, der einen anderen Vektor als Parameter annimmt und eine Kopie erstellt.

  3. Kopieren Sie die drei Werte selbst manuell ( b = new Vector3D(a.x, a.y, a.z) ), wenn Sie die Implementierung von Vector3D .

1voto

Neil N Punkte 24394

Ja, Referenztypen werden per Referenz zugeordnet.

Wenn Sie eine separate Instanz haben möchten, müssen Sie CLONE Ihre Instanz.

Erstellen Sie eine Methode Vector3D.Clone(), die etwa so aussehen würde:

public Vector3D Clone()
{
    return new Vector3D(this.x, this.y, this.x);
}

Dann sollte Ihr Main wie folgt aussehen:

static void Main(string[] args)
{
    Vector3D a, b;
    a = new Vector3D(0, 5, 10);
    b = new Vector3D(0, 0, 0);

    b = a.Clone();
    a.x = 10;

    Console.WriteLine("vector a=" + a.ToString());
    Console.WriteLine("vector b=" + b.ToString());
    Console.ReadKey();
}

Aber wie andere gesagt haben, etwas so klein wie ein Vector3D wäre besser geeignet als eine unveränderliche Struktur

1voto

Tim Coker Punkte 6276

Sie können es zu einer Struktur machen, wie Henk sagt. Und du kannst einen Konstruktor hinzufügen

struct Vector3D
{
    public int x;
    public int y;
    public int z;

    public Vector3D(int x, int y, int z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }
    public override string ToString()
    {
        return string.Format("{0}, {1}, {2}", x, y, z);
    }
}   

Sie können dies auch tun, ohne den Konstruktor hinzuzufügen.

b = new Vector3D() {x=0, y=0, z=0};

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X