C # Getter / Setter problema
-
21-09-2019 - |
Domanda
dire che ho un immobile in una classe:
Vector3 position{get; set;}
Così ho creato un'istanza di quella classe da qualche parte e ora voglio cambiare position.x, che sarebbe impossibile ora perché il getter e setter impostare e ottenere l'intero oggetto. Quindi devo fare un Vector3 temporanea cambiare i suoi valori e poi assegnarlo.
Normalmente avrei rendere la posizione di un campo pubblico affinché problema sarebbe risolto. Ma i cant farlo in questo caso perché la posizione è un'implementazione di un'interfaccia e interfacce non puoi avere campi.
Così come posso risolvere questo il modo migliore.
Modifica: Vector3 è una struttura quindi è un tipo di valore
Soluzione
IMO, la risposta più semplice qui:
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;}
}
Ora si può cambiare obj.X
, obj.Y
e obj.Z
se avete solo bisogno di cambiare una sola dimensione, o cambiare obj.Position
di cambiare tutto.
Se è necessario il nome position
per implementare un'interfaccia, quindi farlo in modo esplicito:
Vector3 IWhateverInterface.position {
get {return position;}
set {position = value;}
}
Altri suggerimenti
È la soluzione semplice in qualche modo non accettabile?
foo.position = new Vector(newX, foo.position.Y, foo.position.Z);
Cosa c'è di sbagliato in questo? Sembra perfettamente lineare.
Questo è uno dei problemi con tipi di valore mutabili. È possibile creare una nuova istanza del tipo di valore con il nuovo valore X
e riassegnare in alla proprietà. È possibile effettuare la creazione dell'istanza più facile, fornendo utili costruttori o l'aggiunta di metodi che restituiscono un oggetto modificato (invece di modificare il valore).
Pre-P.S : Sega troppo tardi che Vector3
è un tipo di valore; il seguente post, pertanto, non sarà di grande aiuto. Ci scusiamo per questo errore.
Bene, mentre le interfacce non possono avere campi, possono avere proprietà, per esempio:.
interface IVector3
{
double X { get; set; }
double Y { get; set; }
double Z { get; set; }
}
Nel vostro Vector3
, è sufficiente implementare quelli come tutto il resto:
class Vector3 : IVector3
{
double IVector3.X
{
get { ... }
set { ... }
}
...
}
Ora torna alla vostra proprietà position
. Legare la proprietà di un'istanza fissa durante l'inizializzazione e solo fornire un getter:
Vector3 position
{
get
{
return _position;
}
}
private Vector3 _position = new Vector3(...);
Rendendo la proprietà di sola lettura (es. Senza setter), si garantisce che non sarà sostituito con un nuovo oggetto Vector3
. Invece, si legano a un'istanza fissa (_position
) in fase di inizializzazione. Ma si può cambiare il Vector3
assegnando nuovi valori position.X
, position.Y
o position.Z
.