Когда класс должен использовать свои собственные геттеры/сеттеры или напрямую обращаться к членам?
При создании сеттеров и геттеров в Eclipse один из вариантов - использовать геттеры и сеттеры внутри класса, а не напрямую обращаться к членам класса. Является ли этот уровень внутренней инкапсуляции класса полезной или он делает хорошую идею на один шаг слишком далеко?
DUPE: Должны ли вы использовать свойства accessor внутри класса или только вне класса?
Ответы
Ответ 1
Я думаю, что это хорошая идея, если вы хотите, чтобы возникли потенциальные побочные эффекты - проверка, ведение журнала и т.д. (В С# я хотел бы объявить переменную и свойство и сказать, что единственный доступ к переменной через свойство.)
Иногда вам может показаться, что вам нужно точно установить переменную, потому что вы не хотите побочных эффектов. Например, вам может потребоваться установить две переменные вместе, и оба состояния "before" и "after" действительны, но при установке какого-либо свойства индивидуально будет активирована проверка.
Ответ 2
Это может быть полезно, если вы разрешаете производным классам переопределять ваши получатели. Таким образом, использование геттеров даже изнутри класса будет держать ваш дизайн расширяемым.
По-моему, это то, что нужно определить в руководстве по кодированию.
Ответ 3
Короткий ответ: "это зависит":)
Эрик Липперт имеет отличную статью о "Автоматические против явных свойств" , которая касается этой проблемы, хотя и с немного другого угла.
По существу, вопрос, который вам нужно задать, это:
"Внутри класса [есть] желаемая семантика доступа к этому... свойству, отличному от желаемой семантики доступа к свойству извне?"
Если семантика одинакова, ваш класс должен использовать свои собственные свойства. Если семантика различна, вашему классу необходимо будет непосредственно манипулировать полями поддержки.
Ответ 4
Это полезно, например, когда у вас есть сеттеры, которые выполняют дополнительные действия, такие как установка грязного флага или уведомления наблюдателей.
Для getters вы можете вместо доступа к полю вычислить значение при изменении представления.
Ответ 5
Я нахожу, что я делаю это порой - особенно когда я требую, или сильно ожидаю, что мне понадобится, какой-то логин для получения или настройки (и проверки вокруг них) членов.
Я нахожу, что наличие частных/внутренних свойств помогает в этих случаях.
Но я, конечно, не делаю этого для любого члена.
Последний .NET/VS действительно помогает здесь, поскольку вы можете объявить свойство как таковое:
public string SomeProperty
{
get;
set;
}
и он эффективно создает memebr за сценой. Я знаю, что это вам не поможет, но я подумал, что это может быть интересно: -)
Ответ 6
Если вы хотите, чтобы этот член был привязан к базе данных Winform или WPF, я считаю, что вам нужно объявить его как свойство. Я примерно на 95 процентов уверен, что для привязки данных требуется свойство (синтаксис getter/setting). У меня есть небольшое решение wpf, которое демонстрирует это, но я не вижу способа прикрепить его здесь.
Здесь код: (построенный с VS 2008 SP1, таргетинг .net 3.5 - я использовал проект WPF).
В проекте WPF есть 2 объекта: главное окно (окно1) и объект, который мы тестируем (DataObject)
В окне метки есть привязка к свойству Name в экземпляре объекта данных. Если вы преобразуете свойство Name в поле (удалите геттер/сеттер), привязка данных перестанет работать.
Window1.xaml:
<Window x:Class="WpfDatabinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Label Name ="Label1" Height="28" Margin="12,24,37,0" VerticalAlignment="Top" Content="{Binding Name}"></Label>
</Grid>
Window1.xaml.cs
using System;
using System.Windows;
namespace WpfDatabinding
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
private DataObject ADataObject;
public Window1()
{
InitializeComponent();
this.ADataObject = new DataObject();
this.ADataObject.Name = "Hello!";
this.DataContext = this.ADataObject;
}
}
}
namespace WpfDatabinding
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
private DataObject ADataObject;
public Window1()
{
InitializeComponent();
this.ADataObject = new DataObject();
this.ADataObject.Name = "Hello!";
this.DataContext = this.ADataObject;
}
}
}
DataObject.cs:
namespace WpfDatabinding
{
public class DataObject
{
// convert this to a field, and databinding will stop working
public string Name
{
get;
set;
}
}
}
Ответ 7
Когда вам нужно расширить поведение получателя/сеттера для класса, полезно иметь инкапсулированные поля (getters/seters вместо прямого доступа к члену).
Однако в наследстве концептуально интересно сохранить участников вашего класса, если его подклассы не должны знать о своих личных вещах. Поэтому иногда поле является приватным для реализации класса, поэтому даже подклассы не знают об этом.