Frage

Sagen Sie, ich habe eine Eigenschaft in einer Klasse:

Vector3 position{get; set;}

Ich erstelle also irgendwo eine Instanz dieser Klasse und jetzt möchte ich die Position ändern. Daher muss ich einen temporären Vektor 3 ändern3 ändern seine Werte und zuordnen sie dann zu.

Normalerweise würde ich Position ein öffentliches Feld machen, damit dieses Problem gelöst wird. Aber ich kann es in diesem Fall nicht tun, da Position eine Implementierung einer Schnittstelle ist und Schnittstellen keine Felder haben können.

Wie kann ich das den besten Weg lösen?

Bearbeiten: Vector3 ist eine Struktur, also ist es ein Werttyp

War es hilfreich?

Lösung

IMO, die einfachste Antwort hier:

private Vector3 position;
public Vector3 Position {
    get {return position;}
    set {position = value;} // with @Mehrdad's optimisation
}
public float X {
    get {return position.X;}
    set {position.X = value;}
}
public float Y {
    get {return position.Y;}
    set {position.Y = value;}
}
public float Z {
    get {return position.Z;}
    set {position.Z = value;}
}

Jetzt können Sie sich ändern obj.X, obj.Y und obj.Z Wenn Sie nur eine Dimension ändern oder ändern müssen obj.Position alles ändern.

Wenn Sie den Namen benötigen position Um eine Schnittstelle zu implementieren, dann tun Sie sie explizit:

Vector3 IWhateverInterface.position {
    get {return position;}
    set {position = value;}
}

Andere Tipps

Ist die unkomplizierte Lösung irgendwie nicht akzeptabel?

foo.position = new Vector(newX, foo.position.Y, foo.position.Z);

Was stimmt damit nicht? Es scheint absolut einfach.

Dies ist eines der Probleme mit mummernden Werttypen. Sie können eine neue Instanz des Werttyps mit dem neuen erstellen X Wert und Neuzuweisung in das Eigentum. Sie können die Instanzerstellung erleichtern, indem Sie nützliche Konstruktoren bereitstellen oder Methoden hinzufügen, die ein modifiziertes Objekt zurückgeben (anstatt den Wert zu ändern).

Pre-Ps: Sah zu spät das Vector3 ist ein Werttyp; Der folgende Beitrag wird daher nicht viel Hilfe sein. Entschuldigung für diesen Fehler.

Nun, während Schnittstellen keine Felder haben, aber sie kann Eigenschaften haben, z. B.:

interface IVector3
{
    double X { get; set; }
    double Y { get; set; }
    double Z { get; set; }
}

In deiner Vector3, Sie implementieren einfach diejenigen wie alles andere:

class Vector3 : IVector3
{
    double IVector3.X
    {
        get { ... }
        set { ... } 
    }
    ...
}

Jetzt zurück zu deinem position Eigentum. Sie binden die Eigenschaft während der Initialisierung an eine feste Instanz und bieten nur einen Getter:

Vector3 position
{
    get
    {
        return _position;
    }
}

private Vector3 _position = new Vector3(...);

Wenn Sie die Eigenschaft schreibgeschützt machen (dh kein Setter), stellen Sie sicher, dass sie nicht durch ein neues ersetzt wird Vector3 Objekt. Stattdessen binden Sie es an eine feste Instanz (_position) zur Initialisierungszeit. Aber Sie können die ändern Vector3 durch Zuweisen neuer Werte an position.X, position.Y, oder position.Z.

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