如何在大量属性上实现延迟加载

时间:2014-01-27 20:44:43

标签: c# generics optimization lazy-loading solution

我有一个包含多个属性代码的类,如此代码段:

IFoo a;
public IFoo Foo
{
    get
    {
        if (a == null)
        {
            // load a
            ...
        }
        return a;
    }
}


IBar b;
public IBar Bar
{
    get
    {
        if (b == null)
        {
            // load b
            ...
        }
        return b;
    }
}

我有超过20个Propertys,其中界面总是不同,而不是加载结构。 我觉得这段代码不是最优的。

有更好的解决方案吗?也许是通用的东西,例如(不工作):

T b;
public T Bar<T>
{
    get
    {
        if (b == null)
        {
            // load b
            ...
        }
        return b;
    }
}

4 个答案:

答案 0 :(得分:1)

尝试使用Lazy<T>构造,这实际上是代码的语法糖。

来自MSDN的示例(定义如何在构造函数中将对象延迟加载为Func,线程安全):

lazyLargeObject = new Lazy<LargeObject>(() => 
{
    LargeObject large = new LargeObject(Thread.CurrentThread.ManagedThreadId);
    // Perform additional initialization here. 
    return large;
});

然后在您第一次尝试访问该对象时将获取该值:

LargeObject large = lazyLargeObject.Value;

答案 1 :(得分:1)

您正在寻找的是Lazy Loading Pattern的实施。

有一些公共方法可以完成它,例如:虚拟代理,价值持有者和幽灵。 正如@bjeger所提到的,你可以使用Lazy&lt; T&gt;。解决您的问题,但查看和研究上述实施将让您知道哪些更适合您的具体案例。

以下是使用C#的一些示例:Four Ways to Implement Lazy Loading in C#

答案 2 :(得分:0)

使用LazyInitializer.EnsureInitialized

using System.Threading;

IFoo a;
public IFoo Foo
{
    get
    {
        return LazyInitializer.EnsureInitialized(ref a, () => { /* load a */ });
    } 
}

答案 3 :(得分:0)

至少获得较短属性的一种方法是Lazy&lt; T&gt;:

Lazy<IBar> b = new Lazy<IBar>();
public IBar Bar
{
  get
  {
    return b.Value;
  }
}

首次调用b.Value时,它将调用IBar的默认构造。有多个重载与线程安全和调用其他构造函数有关。请参阅:http://msdn.microsoft.com/en-us/library/dd642331(v=vs.110).aspx