在访问 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
。
我正在处理一些使用 .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
。