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