是否有一个懒洋洋地评估财产以下两种方法(财产与支持字段与默认值属性)之间的差异,或者是他们相同呢?
// (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
,没有实例应该曾经创造。
嗯,其实,不,他们没有不同。
但是,这只是一个假设你要知道,他们没有任何工作,至少不是我希望你打算做他们的方式。
你看,这句法:
<property declaration> = <expression>;
声明的属性,这将在施工所属类型的执行的初始化程序。
所以这:
private static readonly Lazy<Foo> instance = new Lazy<Foo>();
public static Foo Instance { get; } = instance.Value;
更是不可以偷懒的。它将声明并构建Lazy<Foo>
(虽然你可能在这里失踪,吸气代表以及即使这编译),但是当你申报财产,你最终与物业评估在所属类型的建设,从而懒惰对象它变得不懒。
第二个具有完全相同的问题,您构建并使它成为非懒立即评估懒对象。
正确的方法,而这只能在排序第一的语法形式的实现,是使用属性没有初始化,无论是这样的:
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;
这将宣布一个getter身体不执行,直到你实际读取属性。
TL; DR概括起来讲,你给了两个例子都没有什么不同,但他们都(可能)错了,你需要改变的财产申报进行修复。
除了由answer给出的优秀Lasse Vågsæther Karlsen,我想进一步猜测和假设OP是辛格尔顿后实施。这里是一个完全偷懒的做法。
Approach 1
public sealed class Singleton {
//Private ctor of course :P
private Singleton() {}
// Instance property to access Singleton Instance
public static Singleton Instance { get { return Nested.instance; } }
private class Nested {
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested() { }
internal static readonly Singleton instance = new Singleton();
}
}
Approach 2
public sealed class Singleton
{
private static readonly Lazy<Singleton> lazy =
new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance { get { return lazy.Value; } }
private Singleton()
{
}
}