views:

84

answers:

4

In C#,

Is there a way to turn an automatic property into a lazy loaded automatic property with a specified default value?

Essentially, I am trying to turn this...

private string _SomeVariable

public string SomeVariable
{
     get
     {
          if(_SomeVariable == null)
          {
             _SomeVariable = SomeClass.IOnlyWantToCallYouOnce();
          }

          return _SomeVariable;
     }
}

into something different, where I can specify the default and it handles the rest automatically...

[SetUsing(SomeClass.IOnlyWantToCallYouOnce())]
public string SomeVariable {get; private set;}
A: 

I don't think this is possible with pure C#. But you could do it using an IL rewriter like PostSharp. For example it allows you to add handlers before and after functions depending on attributes.

CodeInChaos
+5  A: 

No there is not. Auto-implemented properties only function to implement the most basic of properties: backing field with getter and setter. It doesn't support this type of customization.

However you can use the 4.0 Lazy<T> type to create this pattern

private Lazy<string> _someVariable =new Lazy<string>(SomeClass.IOnlyWantToCallYouOnce);
public string SomeVariable {
  get { return _someVariable.Value; }
}

This code will lazily calculate the value of _someVariable the first time the Value expression is called. It will only be calculated once and will cache the value for future uses of the Value property

JaredPar
Actually, it looks to me like Lazy implements the singleton pattern. That is not my goal...my goal is create a lazy loaded property that is lazily instantiated but disposed along with the instance of the class in which it lives. Lazy does not seem to be performing that way.
Matthew
+3  A: 

Not like that, parameters for attributes must be constant in value, you cannot call code (Even static code).

You may however be able to implement something with PostSharp's Aspects.

Check them out:

PostSharp

Aren
A: 

Probably the most concise you can get is to use the null-coalescing operator:

get { _SomeVariable ?? _SomeVariable = SomeClass.IOnlyWantToCallYouOnce(); }
Gabe Moothart
In the case `IOnlyWantToCallYouOnce` returns `null` it will call it more than once.
JaredPar