Чтобы ответить # 1: подумайте, как бы это выглядело без автоматически сгенерированного свойства. У вас будет Property { get { return xxx; } }
Вот где копия сделана. То, что выглядит как ссылка на свойство, на самом деле вызывает метод получения. Ожидаете ли вы редактирования на месте, если у вас есть:
private MutableStruct v;
public MutableStruct f()
{
return v;
}
f() = new MutableStruct();
Конечно, нет, мы все зависим от возврата, чтобы сделать копию структуры, чтобы частная переменная была защищена от внешней модификации. Вот почему это работает так, как работает.
Теперь, если вы думаете, что установщик свойств должен был автоматически вызываться с результирующим значением, позвольте мне отметить, что чрезвычайно сложно невозможно узнать во время компиляции, если вызов один из методов структуры делает изменение (рассмотрите, определена ли структура в другой сборке). И возвращение значения не просто неэффективно, но и безопасно, это может нарушить правильность. Рассмотрим многопоточный сценарий, когда потоки, которые только читали из свойства, защищенного ReaderWriterLock, внезапно записывают обратно в него. Все виды боли и несчастья будут происходить. Таким образом, компилятор C # автоматически устанавливает свойство для результата ваших вычислений, просто не вариант.
РЕДАКТИРОВАТЬ: вам было интересно, почему установка поля в структуре генерирует сообщение об ошибке, но при вызове метода, чтобы сделать то же самое, нет. Ну, у метода могут быть полезные побочные эффекты, поэтому вам все еще нужно вызывать его для временной копии структуры. Рассмотрим следующий вариант:
struct Mutable
{
public static int Sum = 0;
public int x;
public Mutable(int x) { this.x = x; }
public void Total() { Sum += x; }
}
class Container
{
public Mutable Field;
public Mutable Property { get; set; }
}
class Program
{
static void Main(string[] args)
{
Container c = new Container();
c.Field = new Mutable(1);
c.Property = new Mutable(2);
c.Field.Total();
c.Property.Total();
Console.Out.WriteLine(Mutable.Sum);
}
}