首页 > 解决方案 > 在访问 LazyLoadObject.Value 之前使用 IsValueCreated

问题描述

我正在使用一些使用 .Net 4 Lazy 加载的 C# 代码,但我对它并不十分熟悉。我试图弄清楚这个特定的代码是否无用。

最初的属性和代码在同一个类中,但现在我已将代码移动到不再有权访问私有“lazyRecords”属性的外部类。我想知道检查“lazyRecords.IsValueCreated”的意义是什么,因为尚未调用lazyRecords.Value,它不会总是错误的吗?还是检查另一个线程是否以某种方式调用了该值?还是在导致未加载对象的线程异常的情况下这样做?

财产:

private Lazy<List<Record>> lazyRecords;
public List<Record> Records
{
    get
    {
        return lazyRecords.Value;
    }
    set
    {
        lazyRecords = new Lazy<List<Record>>(() => value);
    }
}

代码:

public Category LoadCategory(BaseClient client)
{
    Category category = new Category();
    category.Records = client.RecordClient.GetRecordsByCategoryID(category.ID);

    if (lazyRecords.IsValueCreated)
    {
        category.WorldRecord = category.Records.FirstOrDefault();
    }
    else
    {
       category.WorldRecord = client.RecordClient.GetWorldRecord(category.ID);
    }
}

标签: c#lazy-loading

解决方案


该代码非常没用,是的。为了帮助你理解为什么,考虑这个非常小的版本Lazy(真正的类有更多的选项和逻辑来处理多个线程,但这是一个粗略的想法):

public class Lazy<T>
{
    private readonly Func<T> _creator;
    private T _cachedValue;

    public Lazy(Func<T> creator) => _creator = creator;

    public bool IsValueCreated { get; private set; }

    public T Value
    {
        get
        {
            if (!IsValueCreated)
            {
                _cachedValue = _creator();
                IsValueCreated = true;
            }

            return _cachedValue;
        }
    }
}

Value传递给构造函数的委托在第一次被请求时被按需调用。在您发布的代码中,这没有任何意义,因为委托只是将value传递的值返回到设置器中。

至于LoadCategory方法,您发布的代码很难破译。它直接访问lazyRecords,暗示它是同一个类的方法。但随后它访问Records不同的对象。


推荐阅读