C# Getter/Setter Problem
-
21-09-2019 - |
Pergunta
Digamos que eu tenho uma propriedade em uma aula:
Vector3 position{get; set;}
Por isso, crio uma instância dessa classe em algum lugar e agora quero mudar de posição.x, isso seria impossível agora porque o conjunto Getter e Setter e obtenha todo o objeto. Então, eu tenho que fazer com que um vetor3 temporário 3 altere seus valores e depois atribuí -lo.
Normalmente, eu fazia posição em um campo público para que o problema fosse resolvido. Mas não posso fazer isso neste caso, porque a posição é uma implementação de uma interface e as interfaces não podem ter campos.
Então, como posso resolver isso da melhor maneira.
Editar: Vector3 é uma estrutura, então é um tipo de valor
Solução
IMO, a resposta mais fácil aqui:
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;}
}
Agora você pode mudar obj.X
, obj.Y
e obj.Z
Se você só precisa mudar uma dimensão ou mudar obj.Position
para mudar tudo.
Se você precisar do nome position
Para implementar uma interface, faça -o explicitamente:
Vector3 IWhateverInterface.position {
get {return position;}
set {position = value;}
}
Outras dicas
A solução direta é de alguma forma não aceitável?
foo.position = new Vector(newX, foo.position.Y, foo.position.Z);
O que há de errado nisso? Parece perfeitamente direto.
Esse é um dos problemas com os tipos de valor mutável. Você pode criar uma nova instância do tipo de valor com o novo X
valor e reatribuir para a propriedade. Você pode facilitar a criação da instância, fornecendo construtores úteis ou adicionando métodos que retornam um objeto modificado (em vez de modificar o valor).
Pré-ps: Vi tarde demais Vector3
é um tipo de valor; A postagem a seguir, portanto, não ajudará muito. Desculpe por esse erro.
Bem, enquanto interfaces não podem ter campos, eles posso tem propriedades, por exemplo:
interface IVector3
{
double X { get; set; }
double Y { get; set; }
double Z { get; set; }
}
Na tua Vector3
, você simplesmente implementa aqueles como tudo:
class Vector3 : IVector3
{
double IVector3.X
{
get { ... }
set { ... }
}
...
}
Agora de volta ao seu position
propriedade. Você vincula a propriedade a uma instância fixa durante a inicialização e fornece apenas um getter:
Vector3 position
{
get
{
return _position;
}
}
private Vector3 _position = new Vector3(...);
Ao fazer a propriedade somente leitura (por exemplo, sem setter), você garante que ela não seja substituída por um novo Vector3
objeto. Em vez disso, você o amarra a uma instância fixa (_position
) no tempo de inicialização. Mas você pode mudar o Vector3
atribuindo novos valores a position.X
, position.Y
, ou position.Z
.