Acho que muitas pessoas estão ficando confusas aqui, esse problema específico está relacionado ao entendimento de que as propriedades do tipo de valor retornam uma cópia do tipo de valor (como nos métodos e indexadores), e os campos do tipo de valor são acessados diretamente . O código a seguir faz exatamente o que você está tentando alcançar acessando diretamente o campo de apoio da propriedade (note: expressar uma propriedade em sua forma detalhada com um campo de apoio é o equivalente a uma propriedade automática, mas tem a vantagem de que em nosso código podemos acesse diretamente o campo de apoio):
class Program
{
static void Main(string[] args)
{
var myClass = new MyClass();
myClass.SetOrigin();
Debug.Assert(myClass.Origin.X == 10); //succeeds
}
}
class MyClass
{
private Point _origin;
public Point Origin
{
get => _origin;
set => _origin = value;
}
public void SetOrigin()
{
_origin.X = 10; //this works
//Origin.X = 10; // fails with CS1612;
}
}
O erro que você está recebendo é uma consequência indireta de não entender que uma propriedade retorna uma cópia de um tipo de valor. Se você receber uma cópia de um tipo de valor e não a atribuir a uma variável local, as alterações feitas nessa cópia nunca poderão ser lidas e, portanto, o compilador gera isso como um erro, pois isso não pode ser intencional. Se atribuirmos a cópia a uma variável local, podemos alterar o valor de X, mas ele será alterado apenas na cópia local, que corrige o erro do tempo de compilação, mas não terá o efeito desejado de modificar a propriedade Origin. O código a seguir ilustra isso, pois o erro de compilação desapareceu, mas a declaração de depuração falhará:
class Program
{
static void Main(string[] args)
{
var myClass = new MyClass();
myClass.SetOrigin();
Debug.Assert(myClass.Origin.X == 10); //throws error
}
}
class MyClass
{
private Point _origin;
public Point Origin
{
get => _origin;
set => _origin = value;
}
public void SetOrigin()
{
var origin = Origin;
origin.X = 10; //this is only changing the value of the local copy
}
}