Lazy getter

Topics: C# Language Design
Oct 24, 2014 at 2:10 PM
Edited Oct 24, 2014 at 2:15 PM
Hi everyone,

In numerous cases, we have the following implementation of a property:
private string _value;
public string Value
{
  get 
  {
    return _value ?? (_value = SomeMethod());
  }
}
Or for value types (since the backing field must be nullable):
private bool? _isValid;
public bool IsValid
{
  get 
  {
    return (_isValid?? (_isValid= SomeMethod())).Value;
  }
}
Using a Lazy<T> isn't very convenient as you'll have to set the value in the constructor, (far away from the property) AND its type is a Lazy<T> where one only wanted a T.


It would be nice to have a syntax such as
public string Value { get once { return SomeMethod(); } }
that would use a backing field and evaluate the body only once. Of course, it would be better if some thread-safe initialization were done.

What does other think?
Oct 24, 2014 at 2:39 PM
It has some common points with another topic I've just discovered: https://roslyn.codeplex.com/discussions/550266, though the scope of this topic is much narrower and couldn't be achieved cleanly with implicit backing field.
Oct 24, 2014 at 8:47 PM
Edited Oct 24, 2014 at 8:47 PM
A simpler way to do it would be to provide some syntactic sugar for Lazy<T>, simply copying the Scala model:
public readonly lazy string Value = SomeMethod();

public bool IsValid { lazy get { return CalculateIsValid(); } }
That's a nice simple piece of syntactic sugar, but I'm not sure how worthy it is of dedicating new team resources towards it, to be honest (even in the next cycle).
Oct 25, 2014 at 7:45 PM
Skiminok wrote:
A simpler way to do it would be to provide some syntactic sugar for Lazy<T>, simply copying the Scala model:
public readonly lazy string Value = SomeMethod();

public bool IsValid { lazy get { return CalculateIsValid(); } }
That's a nice simple piece of syntactic sugar, but I'm not sure how worthy it is of dedicating new team resources towards it, to be honest (even in the next cycle).
It's nice and clean indeed. I don't know how much it would cost, but maybe it's cheap :)
Oct 26, 2014 at 1:51 PM
Just going to poke this thread with this ongoing discussion as well.

Seems that it's not uncommon to want to add behavior around auto-properties without buying into full properties. Some form of meta-programming could allow that by allowing attributes or separate code dictate how specific auto-properties behave. Through this I could picture something like:
[LazyProperty(nameof(this.CalculateIsValid))]
public bool IsValid { get; }

private bool CalculateIsValid() {
    // logic here
}