我有这样的房产:
private DataSet dsFoo = null;
public DataSet Foo {
get {
if (dsFoo == null) {
dsFoo = PopulateFoo();
}
return dsFoo;
}
}
感谢C#6,我将其缩写为:
private DataSet dsFoo = null;
public DataSet Foo => dsFoo ?? (dsFoo = PopulateFoo());
有没有进一步缩写这个属性,以便dsFoo的声明与属性声明一样?或者就这一点而言呢?
答案 0 :(得分:1)
有没有进一步缩写这个属性,以便dsFoo的声明与属性声明在同一行?
最终,你需要一个支持领域。要反映延迟创建的值的语义,您可以使用Lazy<T>
,如下所示:
private Lazy<DataSet> foo = new Lazy<DataSet>(PopulateFoo);
public DataSet Foo => foo.Value;
作为在单一陈述中复制上述内容的学术(而非推荐)解决方案,可以在C#6中实现类似的行为:
public LazyImplicit<DataSet> Foo { get; } = new LazyImplicit<DataSet>(PopulateFoo);
其中LazyImplicit
定义为:
class LazyImplicit<T> : Lazy<T>
{
public LazyImplicit(Func<T> valueFactory) : base(valueFactory) { }
public static implicit operator T(LazyImplicit<T> obj) => obj.Value;
}
从LazyImplicit<T>
到T
的隐式转换允许您声明DataSet n = YourClass.Foo
并同时确保仅在需要时调用PopulateFoo
,每个实例不超过一次。但是,方法签名将显示Foo
返回LazyImplicit<DataSet>
而不是DataSet
,这是非惯用的,并且要求调用者知道隐式转换存在。