Должны ли вы использовать свойства accessor внутри класса или только вне класса?

У меня есть класс 'Data', который использует getter для доступа к некоторому массиву. Если массив равен NULL, то я хочу, чтобы Data получал доступ к файлу, заполнял массив и возвращал определенное значение.

Теперь вот мой вопрос:

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

Проблема, с которой я использую аксессоры из класса, заключается в том, что я получаю бесконечные циклы, поскольку вызывающий класс ищет некоторую информацию в Data.array, getter находит нулевой массив, поэтому он получает его из файла, и эта функция в конечном итоге вызывает геттер снова изнутри Data, массив снова имеет значение null, и мы застреваем в бесконечном цикле.

ИЗМЕНИТЬ:

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

Ответ 1

Я согласен с krosenvold и хочу немного обобщить его совет:

Не используйте свойства getters и seters для дорогостоящих операций, например, чтение файла или доступ к сети. Используйте явные вызовы функций для дорогостоящих операций.

Как правило, пользователи класса не ожидают, что простой поиск или присвоение свойств может занять много времени.

Это также рекомендуется в Руководстве по разработке Microsoft Framework.;

Использовать метод, а не свойство в следующих ситуациях.

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

Ответ 2

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

Можете ли вы разместить геттер и сеттер для одного из этих свойств? Может быть, мы можем помочь отладить его.

Ответ 3

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

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

Ответ 4

Нет. Я не верю, что вам следует, причина: поддерживаемый код.

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

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

Они также могут быть свистком производительности, что должно быть простым поиском, может стать неприятным, если кто-то поместит код базы данных в свойствах - и я тоже видел, как люди это делают!

Принцип KISS по-прежнему действует после всех этих лет...!

Ответ 5

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

Эрик Липперт недавно написал блог на эту тему в нескольких сообщениях: -

automatic-vs-explicit-properties
future-proofing-a-design

Ответ 6

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

Ответ 7

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

Ответ 8

Я предполагаю, что вы пытаетесь реализовать, это своего рода свойство lazy-load, в котором вы загружаете данные только тогда, когда они доступны в первый раз.

В таком случае я бы использовал следующий подход для предотвращения бесконечного цикла:

private MyData _data = null;

public MyData Data
{
  get
  {
    if (_data == null)
      _data = LoadDataFromFile();
    return _data;
  }
}

private MyData LoadDataFromFile()
{
  // ...
}

Другими словами:

  • не выполнять сеттер
  • всегда используйте свойство для доступа к данным (никогда не используйте поле напрямую)

Ответ 9

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

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