懒惰的财产需要"这个"

def*_*mer 5 .net c# lazy-evaluation

这是我拥有的一个属性的示例,尽可能简单地编码

private IEnumerable<int> _blocks;
private bool _blocksEvaluated;
public IEnumerable<int> Blocks
{
    get
    {
        if (!_blocksEvaluated)
        {
            _blocksEvaluated = true;
            _blocks = this.CalculateBlocks(0).FirstOrDefault();
        }
        return _blocks;
    }
}
Run Code Online (Sandbox Code Playgroud)

这很冗长; 如果可能的话,我想让它更简洁.以下是可以接受的......

private Lazy<IEnumerable<int>> _blocks = 
    new Lazy<IEnumerable<int>>(() => this.CalculateBlocks(0).FirstOrDefault());
Run Code Online (Sandbox Code Playgroud)

...但它没有编译.

关键字"this"在静态属性,静态方法或静态字段初始值设定项中无效

所以我想出了以下内容

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()); }
}
Run Code Online (Sandbox Code Playgroud)

哪个我最喜欢,但有更好的方法吗?

注意 - 我意识到可变结构通常是邪恶的,但它们似乎对这个特定问题非常有用.

Mic*_*ter 6

只需在构造函数中初始化您的字段.

public class MyClass
{
    public MyClass()
    {
        _blocks = new Lazy<IEnumerable<int>>(() => this.CalculateBlocks(0).FirstOrDefault());
    }

    private readonly Lazy<IEnumerable<int>> _blocks;
}
Run Code Online (Sandbox Code Playgroud)


Ser*_*rvy 5

this初始化实例字段时不能使用,但您可以简单地在构造函数中初始化它来解决这个问题。

private Lazy<IEnumerable<int>> _blocks;

public MyClass()
{
   _blocks = new Lazy<IEnumerable<int>>(
         () => this.CalculateBlocks(0).FirstOrDefault());
}

public IEnumerable<int> Blocks
{
    get
    {
        return _blocks.Value;
    }
}
Run Code Online (Sandbox Code Playgroud)