对于惰性计算的属性,以下两种方法(具有后备字段的属性和具有默认值的属性)之间是否存在差异?或者它们等效吗?
// (1)
public static class Foo
{
private static readonly Lazy<Foo> instance = new Lazy<Foo>();
public static Foo Instance { get; } = instance.Value;
}
// (2)
public static class Foo
{
public static Foo Instance { get; } = new Lazy<Foo>().Value;
}
我要实现的是,仅在访问Foo
时才创建Foo.Instance
的实例,而不是之前---如此,当从未访问过Foo.Instance
时,则不应该创建任何实例被创造出来。
答案 0 :(得分:3)
实际上,不,它们没有什么不同。
但是,这只是一个假设,请注意,它们也不起作用,至少不是我希望您希望它们起作用的方式。
您会看到以下语法:
<property declaration> = <expression>;
为该属性声明一个初始化程序,该初始化程序将在拥有类型的构造上执行。
所以这个:
private static readonly Lazy<Foo> instance = new Lazy<Foo>();
public static Foo Instance { get; } = instance.Value;
一点也不懒。它会声明并构造一个Lazy<Foo>
(尽管即使编译也可能会在这里丢失getter委托),但是,当您声明该属性时,最终会在构造该属性时对惰性对象进行评估拥有类型,因此变得非惰性。
第二个问题完全相同,您构造并立即评估惰性对象,使其变为非惰性。
正确的方法(只能以第一种语法形式实现)是使用没有初始化程序的属性,要么是这样:
private static readonly Lazy<Foo> instance = new Lazy<Foo>();
public static Foo Instance
{
get { return instance.Value; }
}
或者这个:
private static readonly Lazy<Foo> instance = new Lazy<Foo>();
public static Foo Instance
{
get => instance.Value;
}
或者可能是最好的,就像这样:
private static readonly Lazy<Foo> instance = new Lazy<Foo>();
public static Foo Instance => instance.Value;
这将声明一个吸气剂 body ,直到您实际读取该属性后,该吸气剂才会执行。
TL; DR 综上所述,您给出的两个示例并没有什么不同,但是(可能)它们都是错误的,您需要更改属性声明以对其进行修复。
答案 1 :(得分:0)
除了answer给出的出色的Lasse Vågsæther Karlsen之外,我还要进一步推测并假设OP在Singleton实现之后。这是一种完全懒惰的方法。
{{1}}