C# Getter/Setter -Problem
-
21-09-2019 - |
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
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
.