Myślę, że wiele osób jest tu zdezorientowanych, ten konkretny problem jest związany ze zrozumieniem, że właściwości typu wartości zwracają kopię typu wartości (tak jak w przypadku metod i indeksatorów), a pola typu wartości są dostępne bezpośrednio . Poniższy kod robi dokładnie to, co próbujesz osiągnąć, uzyskując bezpośredni dostęp do pola zapasowego właściwości (uwaga: wyrażenie właściwości w postaci pełnej za pomocą pola zapasowego jest odpowiednikiem właściwości automatycznej, ale ma tę zaletę, że w naszym kodzie możemy uzyskać bezpośredni dostęp do pola zapasowego):
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;
}
}
Otrzymany błąd jest pośrednią konsekwencją niezrozumienia, że właściwość zwraca kopię typu wartości. Jeśli otrzymasz kopię typu wartości i nie przypiszesz jej do zmiennej lokalnej, wszelkie zmiany, które wprowadzisz w tej kopii, nigdy nie mogą zostać odczytane, a zatem kompilator zgłasza to jako błąd, ponieważ nie może to być zamierzone. Jeśli przypiszemy kopię do zmiennej lokalnej, możemy zmienić wartość X, ale zostanie ona zmieniona tylko na kopii lokalnej, co naprawia błąd czasu kompilacji, ale nie będzie miało pożądanego efektu modyfikacji właściwości Origin. Poniższy kod ilustruje to, ponieważ błąd kompilacji zniknął, ale asercja debugowania zakończy się niepowodzeniem:
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
}
}