代码之家  ›  专栏  ›  技术社区  ›  mgmedick

在访问LazyLoadObject之前使用IsValueCreated。价值

  •  0
  • mgmedick  · 技术社区  · 6 年前

    我正在处理一些正在使用的C#代码。Net 4延迟加载,我对它不是非常熟悉。我想弄清楚这段代码是否有用。

    最初,属性和代码位于同一个类中,但现在我将代码移到了一个外部类,该类不再具有访问私有“lazyRecords”属性的权限。我想知道自从lazyRecords之后,检查“lazyRecords.IsValueCreated”有什么意义。值还没有被调用,它不是一直都是假的吗?还是检查另一个线程是否以某种方式调用了该值?还是在线程异常导致无法加载对象的情况下执行此操作?

    财产:

    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);
        }
    }
    
    0 回复  |  直到 6 年前
        1
  •  1
  •   Daniel Earwicker    6 年前

    代码很没用,是的。为了帮助你理解为什么,考虑这个非常小的版本。 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 在另一个物体上。