Я думаю, что многие люди запутываются здесь, эта конкретная проблема связана с пониманием того, что свойства типа значения возвращают копию типа значения (как с методами и индексаторами), и к полям типа значения обращаются напрямую . Следующий код делает именно то, что вы пытаетесь достичь, напрямую обращаясь к полю поддержки свойства (примечание: выражение свойства в его подробной форме с помощью поля поддержки является эквивалентом свойства auto, но имеет то преимущество, что в нашем коде мы можем получить доступ к вспомогательному полю напрямую):
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
}
}