c# - 在 C# 中编写延迟加载属性的简洁方法

标签 c# syntax lazy-loading boilerplate

当我想使用 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;
})

这里没有很多“事件部件”,而且 super 简洁。 还有哪些其他选择?我注意到我经常退回到手动“惰性”构造。

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;
    }
}

至少与 Lazy 方式相比,这具有更少的“事件部件”,而且我可以将所有内容放在一起(不必将一半的逻辑放在构造函数中)。当然这还有很多其他缺点,比如它不是线程安全的。

我还缺少其他选择吗?

附言 我假设有两种不同的答案 - 一种用于真正的线程安全延迟加载,另一种用于简洁版本,您不关心它是否意外被调用两次。

最佳答案

我建议移动 Lazy从类的内部结构到类在方法中的使用方式。急切初始化 Event在类的主体中(包括它的 SubEventCollection ),而不是使用 Event除此之外,使用 Lazy<Event> .

所以,声明:

public class Event 
{
    public SubEventCollection SubEvents { get; private set; }
    public Event()
    {
         using ( var stream = new MemoryStream(DbSubEventsBucket) )
             SubEvents = Serializer.Deserialize<SubEventCollection3>(stream);

         SubEvents.Initialize(this);
    }
}

但是,而不是返回 Event从产生事件的任何东西中,返回一个 Lazy<Event> ,使他们能够根据需要返回更多数据。这也有通知用户 Event 的好处获取事件数据可能是一项代价高昂的操作。

关于c# - 在 C# 中编写延迟加载属性的简洁方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53271662/

相关文章:

Haskell 尝试理解类型类语法

javascript - Electron:惰性元素类型必须解析为类或函数(在生产模式下)

c# - 从 CLI C++ 应用程序加载库内的 C# WPF 表单

c# - .NET 新手套接字问题

python - 打印命令中的python语法错误

haskell - 如何从记录haskell中提取多个值

android - 处理 LazyList 问题

java - 利用 Hibernate 延迟加载?

c# - 在 C#/.NET 的其他语言环境中格式化数字和日期

c# - 如何在 Autofac 中为开放通用注册许多