AngryHacker
AngryHacker

Reputation: 61646

Anyway to further abbreviate this code?

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

Answers (1)

drf
drf

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

Related Questions