Когда я хочу использовать Lazy<T>
и мне нужно сослаться на this
, мне нужно написать много шаблонного кода:
// the private member
private Lazy<SubEventCollection> _SubEvents;
public Event()
{
// needs to be initialized in the constructor because I refer to this
_SubEvents = new Lazy<SubEventCollection3>(CreateSubEvents);
}
// the "core" body
private SubEventCollection CreateSubEvents()
{
SubEventCollection3 collection;
using ( var stream = new MemoryStream(DbSubEventsBucket) )
collection = Serializer.Deserialize<SubEventCollection3>(stream);
collection.Initialize(this);
return collection;
}
// The final property
public SubEventCollection SubEvents => _SubEvents.Value;
Это все действительно необходимо? Кажется, что слишком много шаблонов и все повсюду. Есть ли какие-нибудь ярлыки, которые читаются немного лучше с не так уж много отдельного шаблона вокруг?
Возможно, я мог бы переместить тело в конструктор, но мне бы это тоже не понравилось - то есть вы переместили много важной логики в ваш конструктор.
Мой любимый способ будет похож на Knockout.js / TypeScript.
subEvents = ko.lazyComputed(() =>
{
SubEventCollection3 sub_events;
using ( var stream = new MemoryStream(DbSubEventsBucket) )
sub_events = Serializer.Deserialize<SubEventCollection3>(stream);
sub_events.Initialize(this);
return sub_events;
})
Здесь не так много «движущихся частей» и они очень лаконичны.
Какие еще есть варианты? Я замечаю, что часто возвращаюсь к ручной «ленивой» конструкции.
private SubEventCollection _SubEvents;
public SubEventCollection SubEvents
{
get
{
if ( _SubEvents == null )
{
using ( var stream = new MemoryStream(DbSubEventsBucket) )
collection = Serializer.Deserialize<SubEventCollection3>(stream);
collection.Initialize(this);
_SubEvents = collection;
}
return _SubEvents;
}
}
По крайней мере, здесь меньше «движущихся частей», чем у «Ленивых», и я могу держать все вместе (не нужно вкладывать половину логики в конструктор). Конечно, у этого есть много других недостатков, таких как то, что это не потокобезопасно.
Мне все еще не хватает других альтернатив?
PS
Я предполагаю, что есть два разных ответа - один для истинной поточно-ориентированной ленивой загрузки, а другой - просто для краткой версии, где вам все равно, если ее случайно вызовут дважды.