在访问 LazyLoadObject.Value 之前使用 IsValueCreated

Using IsValueCreated before accessing LazyLoadObject.Value

我正在处理一些使用 .Net 4 延迟加载的 C# 代码,但我不是很熟悉它。我想弄清楚这个特定代码是否无用。

最初 属性 和下面的代码在同一个 class 中,但现在我已将代码移至外部 class,不再可以访问私有 "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);
    }
}

代码很没用,是的。为了帮助您理解原因,请考虑这个非常简单的 Lazy 版本(真正的 class 有更多选项和逻辑来处理多个线程,但这是粗略的想法):

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。在您发布的代码中,这没有意义,因为委托只是 returns 将 value 传递到 setter.

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