我可以在一个 class 中延迟初始化多个变量,还是需要为每个变量创建一个 class?

Can I lazily initialize multiple variables in one class, or do I need to create a class for each?

我在多个应用程序使用的实用程序 class 库中有大约 10 个变量。每个都从数据库加载数据,并且随着我添加变量,启动延迟变得太长,所以我认为是时候重构并延迟初始化所有变量了。这是一个例子:

public static readonly StringCollection BananaTypes = GetBananaTypes();
public static readonly StringCollection FlowerTypes = GetFlowerTypes();
// etc

更改为:

private static StringCollection privateBananaTypes;
public static StringCollection BananaTypes
{
    get
    {
        if (privateBananaTypes == null)
        {
            lock (privateBananaTypes)
            {
                if (privateBananaTypes == null)
                {
                    privateBananaTypes = GetBananaTypesCollection();
                }
            }
        }
        return privateBananaTypes;
    }
}
private static StringCollection privateFlowerTypes;
public static StringCollection FlowerTypes
{
    get
    {
        if (privateFlowerTypes == null)
        {
            lock (privateFlowerTypes)
            {
                if (privateFlowerTypes == null)
                {
                    privateFlowerTypes = GetFlowerTypeCollection();
                }
            }
        }
        return privateFlowerTypes;
    }
}    

所有 Get... 都是包含 class 中的静态方法。当我去使用其中一个 StringCollections 时,我得到一个 ArgumentNullException。

是否每个变量都必须放在单独的 class 中?我可以懒惰地初始化这个 class 中的每个单独变量吗?如果是这样,我该怎么做?现在我认为我第一次使用 class 所有变量都必须初始化,这不是我想要的。

你得到一个 ArgumentNullException 因为你不能 lock 空对象。您需要创建一个不同的对象(始终为非空对象)才能使您的代码正常工作。 (除此之外,在单个 class 中初始化多个惰性变量并没有错。)

或者,.NET 4.0 提供 Lazy<T> class 用于集成的、线程安全的惰性初始化。您上面写的代码可以重写如下:

private static Lazy<StringCollection> privateBananaTypes = new Lazy<StringCollection>(GetBananaTypesCollection);
public static StringCollection BananaTypes
{
    get { return privateBananaTypes.Value; }
}

private static Lazy<StringCollection> privateFlowerTypes = new Lazy<StringCollection>(GetFlowerTypesCollection);
public static StringCollection FlowerTypes
{
    get { return privateFlowerTypes.Value; }
}