#c# #oop #class #object #constructor
#c# #ооп #класс #объект #конструктор
Вопрос:
Есть ли когда-нибудь случай, когда хранение необходимых данных для создания объекта и создание его только тогда, когда это абсолютно необходимо, лучше / эффективнее, чем хранение самого объекта?
Тривиальный пример:
class Bar
{
public string Data { get; set; }
}
class Foo
{
Bar bar;
readonly string barData;
public Foo(string barData)
{
this.barData = barData;
}
public void MaybeCreate(bool create)
{
if (create)
{
bar = new Bar { Data = barData };
}
}
public Bar Bar { get { return bar; } }
}
Комментарии:
1. До времени выполнения ничего не создается. 🙂
Ответ №1:
Это имеет смысл, если объект выполняет какую-то сложную операцию при построении, например, выделяет системные ресурсы.
Вы должны Lazy<T>
помочь вам отложить создание экземпляра объекта. Помимо прочего, в него встроена потокобезопасность, если вам это нужно.
Комментарии:
1. 1 для Lazy<T> , что определенно имеет смысл в этой ситуации
Ответ №2:
В общем, нет. (Если я правильно понимаю ваш вопрос).
Выделения / конструкции дешевы с точки зрения производительности. Если вы не делаете что-то сумасшедшее, создавайте свои объекты, когда это кажется естественным для дизайна — не оптимизируйте преждевременно.
Комментарии:
1. Согласен. Не выполняйте слишком много работы в конструкторе. Гораздо лучше перепроектировать класс, у которого есть havy construtor. Следующая ссылка — рекомендация Google по этому поводу. Очень хорошее объяснение. misko.hevery.com/code-reviewers-guide /…
2. @gmamaladze — не уверен, как «тяжелые конструкторы» относятся к моему вопросу. Этот вопрос больше касается отложенной загрузки, чем создания гибких конструкторов… на самом деле, вы заметите, что конструктор Foo следует принципам, изложенным в вашей ссылке.
Ответ №3:
Да, если создание объекта означает его заполнение, а для его заполнения вам нужно выполнить медленную операцию.
Например,
List<int> ll = returnDataFromDBVeryVerySlowly();
или
Lazy<List<int>> ll = new Lazy<List<int>>(() =>
{
return returnDataFromDBVeryVerySlowly();
});
В первом примере returnDataFromDBVeryVerySlowly
будет вызываться всегда, даже если вам это не нужно. Во втором он будет вызываться только в случае необходимости. Это довольно распространенное явление, например, в ASP.NET где вы хотите иметь «готовое» множество «стандартных» наборов данных, но вы не хотите, чтобы они заполнялись, если они не нужны, и вы хотите поместить их в качестве участников своей страницы, чтобы к ним могли обращаться несколько методов (в противном случае методможно было бы вызвать напрямую returnDataFromDBVeryVerySlowly
)