Что происходит, когда вы присваиваете поля или свойства свойств - PullRequest
1 голос
/ 20 ноября 2008

Допустим, у вас есть свойство как:

Person person1;


public Person Captin{
    get{
        return person1;
    }
    set{
        person1 = value;
    }
}

public void SomeFunction(){
    Captin.name = "Hook"
}

В этом случае, если вы зададите имя для свойства, мы знаем, что новое имя Hook будет применено к базовому значению person1. Что если бы наша реализация была немного другой, скажем:

public Person Captin{
    get{
        return ReadCaptinFromDisk();
    }
    set{
        WriteCaptinToDisk(value);
    }
}

public void SomeFunction(){
    Captin.name = "Hook"
}

В этом случае для правильной установки базового значения нам нужно, чтобы код набора Captin вызывался как часть присваивания Captin.name.

Мне интересно знать, будет ли код набора параметров вызывать набор при назначении полей или вызовов методов для ссылок на свойства. особенно для такого рода ситуации, когда значение необходимо распространить на диск (и т. д.).

Ответы [ 4 ]

4 голосов
/ 20 ноября 2008

Каждый раз, когда вы получаете доступ к вашей собственности Captin, она будет читать с диска. Но если вы измените свойство name, оно не будет записано на диск. Он будет записывать на диск, только если вы сделаете что-то вроде

public void SomeFunction() {
   Person p = Captin;
   p.name = "Hook";
   Captin = p;
}
1 голос
/ 18 июля 2012

Переменная класса, параметр, поле, возвращаемое значение или другое подобное хранилище должно рассматриваться как «идентификатор объекта». Если некоторый объект Foo имеет свойство с именем Bar некоторого типа класса, которое поддерживается полем _Bar, и _Bar содержит «идентификатор объекта # 24601», то оператор Foo.Bar.Text = "George" вызовет Text сеттер на объекте № 24601 со значением "Джордж". Обратите внимание, что этот оператор не изменит сам объект Foo (его поле _Bar будет содержать «идентификатор объекта # 24601» до выполнения оператора и будет по-прежнему удерживать его после); однако, скорее всего, это повлияет на объект # 24601.

Место хранения типа структуры следует рассматривать как содержащее содержимое всех его полей (как открытых, так и закрытых). Если бы Foo.Boz было свойством типа Rectangle (которое является структурой) и вспомогательным полем _Boz, доступ к Foo.Boz создал бы новый временный экземпляр типа Rectangle, все поля которого были бы скопированы из тех, что Foo._Boz. Попытка чтения Foo.Boz.X скопирует все поля _Boz во временный экземпляр, а затем получит доступ к полю X этого экземпляра.

Обратите внимание, что некоторые действительно старые и злые компиляторы C # интерпретируют код, такой как Foo.Boz.X = 5;, как Rectangle temp; temp.X = 5;, отбрасывая полученное значение temp, но не выдавая никакого предупреждения. Такое поведение компилятора заставило некоторых людей объявить, что структуры должны быть «неизменяемыми», чтобы гарантировать, что такой код будет генерировать ошибку компилятора, а не выдавать поддельное поведение. К сожалению, эта вера сохраняется и по сей день, несмотря на то, что любой приличный компилятор запретил бы такой код, даже если X было изменяемым полем.

Обратите внимание, что правильный идиоматический способ обновления свойства изменяемого структурного типа:

  Rectangle temp = MyListOFRectangles[5];
  temp.X = 5;
  MyListOFRectangles[5] = temp;

Если известно, что Rectangle имеет открытое целочисленное поле с именем X, а MyListOfRectangles - это List<Rectangle>, вам не нужно знать о каких-либо других свойствах Rectangle, конструкторы и т. д., чтобы знать, что приведенный выше код изменит MyListOfRectangles[5].X, но не повлияет ни на другое свойство MyListOfRectangles[5], ни на любое свойство MyListOfRectangles[4]. Красиво, понятно и просто. Структуры открытых полей позволяют выполнять поэтапное редактирование значений понятным и непротиворечивым способом, в отличие от любого другого типа данных.

1 голос
/ 20 ноября 2008

Установщик свойства вызывается только тогда, когда кто-то фактически назначает ему свойство напрямую.

Что касается того, в порядке ли ваш код: вопрос документации.

Всякий раз, когда у вас есть свойство, которое возвращает что-то изменчивое, вы должны указать, будут ли какие-либо изменения к нему делать. Вы возвращаете копию своих «реальных» данных, или это реальные данные? Это происходит очень часто, когда свойство (или обычный метод) возвращает коллекцию какого-либо вида - это изменчиво? Что будет, если я его поменяю?

Если вы документируете свою собственность, объясняя, что возвращаемые данные являются просто копией, и изменения нигде не будут отражены, это нормально. Если вы оставите это неоднозначным, тогда возникнут проблемы.

Неизменность устраняет эти проблемы, конечно ...

1 голос
/ 20 ноября 2008

Как отмечает @Joe, он не будет записывать на диск. Я просто хотел добавить, что это потому, что вы используете только геттер, а не сеттер. Пример @ Джо использует оба.

По моему мнению, это действительно плохое использование геттера и нарушает разделение интересов. Вы должны иметь слой данных, который обрабатывает сохранение данных. Логика этого не должна быть в вашем бизнес-объекте.

...