Изучение автоматически реализуемых свойств

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

Public Class foo
{
    public foo() { }  

    public string BarName {get; set;}
}

Я, очевидно, использую переменную BarName во всем своем классе, и теперь мне нужно добавить логику, когда значение свойства установлено (оно должно быть полностью в верхнем регистре, см. Рисунок). Означает ли это, что мне нужно создать частную переменную для BarName, например. _BarName и изменить текущую переменную BarName, используемую в моем классе, на _BarName?

Public Class foo
{
    public foo() {}  

    private string _BarName = "";
    public string BarName 
    { 
        get {return _BarName;}
        set {_BarName = Value.ToString().ToUpper();}
    }
}

Я пытаюсь убедиться, что понимаю последствия использования автоматически реализуемых свойств и что это повлечет за собой в будущем, когда / если мне нужно что-то изменить. Я предполагаю, что рефакторинг, показанный выше, не является нарушение изменения, потому что свойство в основном остается прежним; просто потребовалось немного поработать внутри класса, чтобы сохранить его таким и добавить необходимую логику.

Другой пример, который может быть более значимым, - это то, что мне нужно вызвать какой-то метод, когда используется сеттер или геттер; больше, чем изменение значения.

Это кажется справедливым компромиссом для строк и строк кода для настройки свойств.


person Brettski    schedule 03.10.2008    source источник


Ответы (6)


Означает ли это, что мне нужно создать частную переменную для BarName?

да

и изменить текущую переменную BarName, используемую в моем классе

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

Я предполагаю, что рефакторинг, показанный выше, не является критическим изменением, потому что свойство в основном остается прежним; просто потребовалось немного поработать, чтобы сохранить его таким и добавить необходимую логику.

Правильный.

person hurst    schedule 03.10.2008
comment
Ах, значит, я сам использую свойство для доступа к переменной? Не могу этого сделать, если он только для чтения. Код, который я имел в виду, что нужно изменить, находится / внутри / класса - person Brettski; 03.10.2008
comment
В вашем примере это не только для чтения. Однако теперь, когда вы подняли этот вопрос, я отвечу, что вы можете сделать свойство общедоступным для чтения и конфиденциально настраиваемым с помощью {get; частный набор; } шаблон, который позволит вам писать в него изнутри вашего класса. - person hurst; 03.10.2008

Вам не нужно ничего менять. Автореализуемые свойства - это просто синтаксический сахар. Компилятор за кулисами генерирует частную переменную и логику получения / установки. Если вы добавите свою собственную логику получения / установки, компилятор будет использовать ваш код вместо своего автоматически сгенерированного кода, но что касается пользователей этого свойства, ничего не изменилось; любой код, ссылающийся на вашу собственность, будет продолжать работать.

person Seth Petry-Johnson    schedule 03.10.2008
comment
В ПОРЯДКЕ. Но чтобы представить логику сеттера и получателя, мне нужно изменить код, как в моем примере, верно? - person Brettski; 03.10.2008
comment
Да, все будет нормально. Вызов ToString () для строки немного избыточен, но это никому не повредит. - person Matthew Scharley; 03.10.2008
comment
Что делать, если мне нужно вызвать какой-то метод при вызове геттера или сеттера? - person Brettski; 03.10.2008
comment
Бреттски: Я не уверен, что понимаю ... вы можете вызвать метод из получателя / установщика свойства, как и из любого другого метода. Конструкции get {...} и set {...} сами по себе являются синтаксическим сахаром: компилятор генерирует методы getFoo () и setFoo () за кулисами. - person Seth Petry-Johnson; 03.10.2008

При использовании автоматических свойств вы не получаете прямого доступа к базовой «резервной» переменной и не получаете доступа к фактической логике, которая реализуется в средствах получения и установки свойств. У вас есть доступ только к свойству (следовательно, вы используете BarName во всем коде).

Если теперь вам нужно реализовать определенную логику в установщике, вы больше не можете использовать автоматические свойства и вам нужно реализовать свойство «старомодным» способом. В этом случае вам нужно будет реализовать свою собственную частную поддерживающую переменную (предпочтительный метод, по крайней мере для меня, состоит в том, чтобы назвать частную поддерживающую переменную тем же именем, что и свойство, но с начальным нижним регистром (в данном случае поддерживающая Переменная будет называться barName). Затем вы реализуете соответствующую логику в геттере / сеттере.

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

person Scott Dorman    schedule 03.10.2008

Не используйте автоматические свойства, если вы знаете, что собираетесь проверить этот объект. Эти объекты могут быть объектами домена и т. Д. Например, если у вас есть класс Customer, используйте частные переменные, потому что вам может потребоваться проверка имени, даты рождения и т. Д. Но если вы используете класс Rss, тогда будет нормально просто использовать автоматические свойства поскольку проверка не выполняется, а класс используется только для хранения некоторых данных.

person azamsharp    schedule 03.10.2008

Вы правы насчет рефакторинга, и он действительно ничего не должен сломать.

Независимо от того, действительно ли вам нужно пройти по ссылкам внутри класса на имя свойства и изменить их для ссылки на частное поле, будет зависеть от того, нужен ли внутренний код для доступа к базовому представлению данных, а не от того, как он был представлен. потребители класса. В большинстве случаев вы можете оставить достаточно хорошо в покое.

В вашем простом примере было бы разумно оставить все в покое и убедиться, что никакой внутренний код класса не может подорвать преобразование / форматирование, выполняемое в установщике.

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

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

person Hamish Smith    schedule 03.10.2008

Автоматические свойства - это просто синтаксический сахар, компилятор фактически создает для него закрытый член, но, поскольку он генерируется во время компиляции, вы не можете получить к нему доступ.

А позже, если вы хотите реализовать геттеры и сеттеры для свойства, только тогда вы создаете для него явный закрытый член и добавляете логику.

person David Lay    schedule 03.10.2008