Reputation: 61646
I had a property like this:
private DataSet dsFoo = null;
public DataSet Foo {
get {
if (dsFoo == null) {
dsFoo = PopulateFoo();
}
return dsFoo;
}
}
Thanks to C# 6, I abbreviated it to :
private DataSet dsFoo = null;
public DataSet Foo => dsFoo ?? (dsFoo = PopulateFoo());
Is there anyway to further abbreviate this property so that the declaration of dsFoo is on the same like as the property declaration? Or is this as far as it goes?
Upvotes: 2
Views: 79
Reputation: 8699
Is there anyway to further abbreviate this property so that the declaration of dsFoo is on the same line as the property declaration?
Ultimately, you will need a backing field. To reflect the semantics of a lazily-created value, you can use Lazy<T>
like so:
private Lazy<DataSet> foo = new Lazy<DataSet>(PopulateFoo);
public DataSet Foo => foo.Value;
As an academic (and not recommended) solution to replicating the above in a single statement, similar behavior can be attained in C# 6 with:
public LazyImplicit<DataSet> Foo { get; } = new LazyImplicit<DataSet>(PopulateFoo);
where LazyImplicit
is defined as:
class LazyImplicit<T> : Lazy<T>
{
public LazyImplicit(Func<T> valueFactory) : base(valueFactory) { }
public static implicit operator T(LazyImplicit<T> obj) => obj.Value;
}
The implicit conversion from LazyImplicit<T>
to T
allows you to declare DataSet n = YourClass.Foo
and simultaneously ensure that PopulateFoo
is called only on demand and not more than once per instance. However, the method signature will show the Foo
returning LazyImplicit<DataSet>
rather than DataSet
, which is nonidiomatic and requires the caller to know that the implicit conversion exists.
Upvotes: 1