我可以在一个类中懒惰地初始化多个变量,还是需要为每个变量创建一个类?

时间:2016-02-29 23:28:26

标签: c# lazy-initialization

我在多个应用程序使用的实用程序类库中有大约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 ...都是包含类中的静态方法。当我去使用其中一个StringCollections时,我得到一个ArgumentNullException。

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

1 个答案:

答案 0 :(得分:2)

您收到ArgumentNullException,因为您无法{null} lock。您需要创建一个不同的对象(始终为非null)才能使代码正常工作。 (除此之外,在单个类中初始化多个惰性变量没有任何问题。)

或者,.NET 4.0为集成的,线程安全的延迟初始化提供了Lazy<T>类。您上面编写的代码可以重写如下:

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