Я думаю, що тут багато людей плутаються, саме ця проблема пов'язана з розумінням того, що властивості типу значень повертають копію типу значення (як у методах та індексаторах), і до полів типу значень звертаються безпосередньо . Наступний код робить саме те, чого ви намагаєтеся досягти, звернувшись безпосередньо до резервного поля власності (зауважте: вираження властивості у його багатослівній формі за допомогою резервного поля є еквівалентом властивості авто, але має ту перевагу, що в нашому коді ми можемо отримати прямий доступ до резервного поля):
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;
}
}
Помилка, яку ви отримуєте, є непрямим наслідком нерозуміння того, що властивість повертає копію типу значення. Якщо вам повертається копія типу значення і ви не присвоюєте їй локальну змінну, то будь-які зміни, які ви внесли до цієї копії, ніколи не можна прочитати, і тому компілятор викликає це як помилку, оскільки це не може бути навмисним. Якщо ми присвоїмо копію локальній змінній, то ми можемо змінити значення X, але воно буде змінено лише на локальній копії, яка виправить помилку часу компіляції, але не матиме бажаного ефекту змінити властивість Origin. Наступний код ілюструє це, оскільки помилка компіляції відсутня, але твердження про налагодження не вдасться:
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
}
}