什么是延迟实例化?

6

懒加载是指使用更少的代码来获得相同的结果吗?这通常是一个好习惯(前提是简化/优化代码不会影响可读性和可维护性)。

请参考以下懒加载示例:

public sealed class Singleton
{
    private Singleton()
    {
    }

    public static Singleton Instance { get { return Nested.instance; } }

    private class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

        internal static readonly Singleton instance = new Singleton();
    }
} 

Instance 没有私有属性(我知道这是隐式的),这使它变得延迟——因为我们在 public static Singleton Instance 属性中没有设置器吗?


1
http://msdn.microsoft.com/en-us/library/dd997286.aspx - user981225
1
你为什么不使用 Lazy<T>?看一下这篇文章:msdn: lazy initialization - Tim Schmelter
我已经读过了 - 问题是我没有测试过,而且在工作中我们只使用.Net 2.0(所以我不能使用<T>)- 别问为什么!! - Dave
@DaveRook:这里有一个Lazy<Singleton>:https://dev59.com/OGw15IYBdhLWcg3wFHpZ#6847882 - Tim Schmelter
5个回答

14

假设我们有一个类型的字段,构造它的代价很高。

class Foo
{
    public readonly Expensive expensive = new Expensive();
    ...
}

这段代码的问题在于实例化 Foo 会产生实例化 Expensive 的性能成本,无论是否访问 Expensive 字段。 显然的答案是按需构建实例或者 懒加载 该字段:

class Foo
{
    Expensive _expensive;
    public Expensive
    {
        get
        {
            if (_expensive == null) _expensive = new Expensive();
            return _expensive;
        }
    }
    ...
}

这是延迟实例化。


1
你是在暗示说,如果属性是一个类的话,你可以将每个字段也变成延迟加载吗? - Dave
没有必要对不需要昂贵初始化的任何内容进行惰性实例化。这就是重点所在。您可以通过以下方式使用访问器来处理任何类。 - MoonKnight
1
有一些很好的回答解决了我的问题,但这个回答真正让我恍然大悟,并让我想到更多实现它的方法。虽然把它看作是高效加载而不是惰性加载可能更容易! :) - Dave

6

懒加载是一种实践,只有在第一次需要使用对象时才会加载或初始化它。

如果你的应用程序中有大量组件,这可能会极大地提高性能。

请查看维基百科页面以获得更深入的了解(它包含编码示例)。


1
我看过那个维基页面,但是懒加载、懒初始化、惰性求值、急切初始化等等,让我觉得(在我学习的早期阶段)它们都是不同的。现在我开始意识到懒初始化/懒加载是一回事。 - Dave
1
好吧,这是语义学。它可能意味着不同的事情。一个类可以被懒惰地初始化,但也许这个类也会懒惰地加载媒体数据。 - Kache

5
不,惰性实例化意味着在你实际需要它之前不花费任何时间和资源创建它。
在您的单例示例中,“instance”只是一个空引用,直到实际使用它。当使用它时,然后您花费资源使用“new”实例化对象。

啊 - 因此它在静态方法中 - 只有在需要时才调用它,没有任何先前的操作! - Dave
是的。对于单例模式,未来的调用将只访问已创建的那个实例。 - Kache
是的,我现在知道单例模式了!我没有理解加载类型,谢谢。 - Dave

2

这是一种懒加载模式,因为在第一次调用类Singleton的实例之前不会被创建。


2

惰性初始化是指对象的创建被推迟到第一次使用它时。

完整的参考请参见msdn文章Lazy Initialization

在您的上述代码中,单例类的实例不会被创建,直到您调用它。 因此,在您的代码被调用之前,您的程序将不会使用资源。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接