2013-08-05 9 views
5

Ecco un esempio di una proprietà che ho, codificato nel modo più semplice possibilestruttura pigro richiedendo "questa"

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

Questo è dettagliato; Mi piacerebbe renderlo più conciso se possibile. Il seguente sarebbe accettabile ...

private Lazy<IEnumerable<int>> _blocks = 
    new Lazy<IEnumerable<int>>(() => this.CalculateBlocks(0).FirstOrDefault()); 

... ma non viene compilato.

chiave di 'questo' non è valido per una proprietà statica, metodo statico, o campo statico inizializzatore

Così mi si avvicinò con la seguente

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()); } 
} 

Quale mi piace di più, ma c'è un modo migliore?

Nota: mi rendo conto che le strutture mutabili sono solitamente malvagie, ma sembrano davvero utili per questo particolare problema.

+0

posso chiedere perché è numeroso quando sembri assegnarlo solo 1 singolo valore? – terrybozzio

+0

'CalculateBlocks' restituisce un' IEnumerable > ' –

risposta

6

Basta inizializzare il campo nel costruttore.

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

    private readonly Lazy<IEnumerable<int>> _blocks; 
} 
+0

Questo è, ovviamente, corretto. Purtroppo ora mi sto davvero infastidendo [questo problema] (http://stackoverflow.com/q/4460206/644812), quindi potrei comunque usare la mia struct personalizzata. –

4

Non è possibile utilizzare this durante l'inizializzazione di un campo di istanza, ma si può semplicemente inizializzare nel costruttore per affrontare questo problema.

private Lazy<IEnumerable<int>> _blocks; 

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

public IEnumerable<int> Blocks 
{ 
    get 
    { 
     return _blocks.Value; 
    } 
}