Reputation: 6103
Here is an example of a property I have, coded as simply as possible
private IEnumerable<int> _blocks;
private bool _blocksEvaluated;
public IEnumerable<int> Blocks
{
get
{
if (!_blocksEvaluated)
{
_blocksEvaluated = true;
_blocks = this.CalculateBlocks(0).FirstOrDefault();
}
return _blocks;
}
}
This is verbose; I would like to make it more concise if possible. The following would be acceptable...
private Lazy<IEnumerable<int>> _blocks =
new Lazy<IEnumerable<int>>(() => this.CalculateBlocks(0).FirstOrDefault());
... but it doesn't compile.
Keyword 'this' is not valid in a static property, static method, or static field initializer
So I came up with the following
struct MyLazy<TResult>
{
private bool evaluated;
private TResult result;
public TResult Evaluate(Func<TResult> func)
{
if (!evaluated)
{
evaluated = true;
result = func();
}
return result;
}
}
private MyLazy<IEnumerable<int>> _blocks;
public IEnumerable<int> Blocks
{
get { return _blocks.Evaluate(() => this.CalculateBlocks(0).FirstOrDefault()); }
}
Which I like best, but is there a better way?
Note - I realize that mutable structs are usually evil, but they seem really useful for this one particular problem.
Upvotes: 6
Views: 296
Reputation: 203817
You can't use this
when initializing an instance field, but you can simply initialize it in the constructor to address that.
private Lazy<IEnumerable<int>> _blocks;
public MyClass()
{
_blocks = new Lazy<IEnumerable<int>>(
() => this.CalculateBlocks(0).FirstOrDefault());
}
public IEnumerable<int> Blocks
{
get
{
return _blocks.Value;
}
}
Upvotes: 5
Reputation: 12811
Just initialize your field in the constructor.
public class MyClass
{
public MyClass()
{
_blocks = new Lazy<IEnumerable<int>>(() => this.CalculateBlocks(0).FirstOrDefault());
}
private readonly Lazy<IEnumerable<int>> _blocks;
}
Upvotes: 7