Автореализованные методы считывания и методы set по сравнению с общедоступными полями

Когда вы объявляете ссылочную переменную (т. е. объект), вы действительно создаете указатель на объект. Рассмотрим следующий код, в котором вы объявляете переменную примитивного типа int:

int x;
x = 10;

В этом примере переменная x является int, и Java инициализирует ее для 0. Когда вы назначаете его 10 во второй строке, ваше значение 10 записывается в ячейку памяти, на которую указывает x.

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

Integer num;
num = new Integer(10);

Первая строка объявляет переменную с именем num, но она не содержит примитивного значения. Вместо этого он содержит указатель (потому что тип Integer является ссылочным типом). Поскольку вы еще не указали, что указать на Java, он устанавливает значение null, что означает «Я ничего не указываю».

Во второй строке ключевое слово new используется для создания экземпляра (или создания ) объекту типа Integer и переменной указателя num присваивается этот объект. Теперь вы можете ссылаться на объект, используя оператор разыменования . (точка).

Exception, о котором вы просили, возникает, когда вы объявляете переменную, но не создавали объект. Если вы попытаетесь разыменовать num. Перед созданием объекта вы получите NullPointerException. В самых тривиальных случаях компилятор поймает проблему и сообщит вам, что «num не может быть инициализирован», но иногда вы пишете код, который непосредственно не создает объект.

Например, вы можете имеют следующий метод:

public void doSomething(SomeObject obj) {
   //do something to obj
}

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

doSomething(null);

В этом случае obj имеет значение null. Если метод предназначен для того, чтобы что-то сделать для переданного объекта, целесообразно бросить NullPointerException, потому что это ошибка программиста, и программисту понадобится эта информация для целей отладки.

Альтернативно, там могут быть случаи, когда цель метода заключается не только в том, чтобы работать с переданным в объекте, и поэтому нулевой параметр может быть приемлемым. В этом случае вам нужно будет проверить нулевой параметр и вести себя по-другому. Вы также должны объяснить это в документации. Например, doSomething может быть записано как:

/**
  * @param obj An optional foo for ____. May be null, in which case 
  *  the result will be ____.
  */
public void doSomething(SomeObject obj) {
    if(obj != null) {
       //do something
    } else {
       //do something else
    }
}

Наконец, Как определить исключение & amp; причина использования Трассировки стека

71
задан tclem 3 June 2010 в 02:09
поделиться

16 ответов

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

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

48
ответ дан Cœur 24 November 2019 в 13:05
поделиться

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

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

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

объекты Набора свойств как ДАО, DTOs и экранные объекты исключены из этого правила, потому что это не объекты в реальном "Дизайне OO" значение слова Объект. (Вы не думаете "о Передаче сообщений" к ДАО, Это - просто груда пар атрибут/значение).

-1
ответ дан Bill K 24 November 2019 в 13:05
поделиться

Самый большой difrence - то, что когда-нибудь при изменении внутренней структуры можно все еще поддержать методов get и методы set, как, изменяя их внутреннюю логику, не причиняя пользователям боль API.

0
ответ дан gizmo 24 November 2019 в 13:05
поделиться

Если необходимо измениться, как Вы получаете X и Y в этом случае, Вы могли просто добавить свойства позже. Это - то, что я нахожу наиболее сбивающими с толку. При использовании общедоступных членских переменных можно легко изменить это на свойство позже и использовать частные переменные, названные _x и _y, если необходимо сохранить значение внутренне.

0
ответ дан Kibbee 24 November 2019 в 13:05
поделиться

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

0
ответ дан EricSchaefer 24 November 2019 в 13:05
поделиться

AFAIK сгенерированный интерфейс CIL отличается. При изменении общедоступного участника на свойство, Вы изменяетесь, это - открытый интерфейс и потребность восстановить каждый файл, который использует тот класс. Это не необходимо, если Вы только изменяете реализацию методов get и методов set.

1
ответ дан 24 November 2019 в 13:05
поделиться

Также быть рассмотренным - эффект изменения в общедоступных участниках когда дело доходит до привязки и сериализации. Оба из них часто полагаются на общественные собственности для получения и установленные значения.

2
ответ дан TheZenker 24 November 2019 в 13:05
поделиться

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

1
ответ дан marcospereira 24 November 2019 в 13:05
поделиться

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

9
ответ дан Joseph Daigle 24 November 2019 в 13:05
поделиться

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

C# может рассматривать свойства и переменные по-другому время от времени. Например, Вы не можете передать свойства как касательно или параметры . Таким образом, если необходимо изменить структуру данных по некоторым причинам, и Вы использовали общедоступные переменные, и теперь необходимо использовать свойства, интерфейс должен будет изменить и теперь кодировать то свойство x доступов, может не дольше скомпилировать как он, сделал, когда это был переменный x:

Point pt = new Point();
if(Int32.TryParse(userInput, out pt.x))
{
     Console.WriteLine("x = {0}", pt.x);
     Console.WriteLine("x must be a public variable! Otherwise, this won't compile.");
}

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

8
ответ дан Rob Pilkington 24 November 2019 в 13:05
поделиться

Также намного более просто изменить его на это позже:

public int x { get; private set; }
31
ответ дан Brad Wilson 24 November 2019 в 13:05
поделиться

Setter and Getter enables you to add additional abstraction layer and in pure OOP you should always access the objects via the interface they are providing to the outside world ...

Consider this code, which will save you in asp.net and which it would not be possible without the level of abstraction provided by the setters and getters:

class SomeControl
{

private string _SomeProperty  ;
public string SomeProperty 
{
  if ( _SomeProperty == null ) 
   return (string)Session [ "SomeProperty" ] ;
 else 
   return _SomeProperty ; 
}
}
3
ответ дан 24 November 2019 в 13:05
поделиться

, почему мы только не используем общедоступные поля вместо того, чтобы использовать свойства затем, звонят, средства доступа (получите, установите), когда мы не должны делать проверки?

  1. свойство А является участником, который предоставляет гибкий механизм только для чтения или только для записи
  2. , Свойства могут быть переопределены, но поля не могут быть.
0
ответ дан 24 November 2019 в 13:05
поделиться

Также стоит отметить, что вы не можете сделать автоматические свойства только для чтения и не можете инициализировать их встроенными. Обе эти вещи я бы хотел увидеть в будущих версиях .NET, но я считаю, что вы не можете сделать ни то, ни другое в .NET 4.0.

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

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

1
ответ дан 24 November 2019 в 13:05
поделиться

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

Например:

public string x { get; set; }

и, например, вы уже используете x много раз, и вы не хотите взламывать свой код.

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

Моя идея состоит в том, чтобы добавить новую частную переменную и добавить те же средства получения и установки x.

private string _x;

public string x { 
    get {return _x}; 
    set {
        if (Datetime.TryParse(value)) {
            _x = value;
        }
    }; 
}

Это то, что вы имеете в виду, делая ее гибкой?

3
ответ дан 24 November 2019 в 13:05
поделиться

Кроме того, вы можете устанавливать точки останова на геттеры и сеттеры, но не на поля.

2
ответ дан 24 November 2019 в 13:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: