2013-08-05 13 views
5

यहाँ, एक संपत्ति मैं का एक उदाहरण है बस के रूप में संभवलेज़ी की आवश्यकता होती है "इस"

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

यह वर्बोज़ है के रूप में कोडित संपत्ति; यदि संभव हो तो मैं इसे और अधिक संक्षिप्त बनाना चाहता हूं। निम्न स्वीकार्य होंगे ...

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

... लेकिन यह संकलन नहीं है।

कीवर्ड 'इस' एक स्थिर संपत्ति, स्थैतिक विधि, या स्थिर क्षेत्र प्रारंभकर्ता

में मान्य नहीं है तो मैं निम्नलिखित

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

कौन सा मैं सबसे ज्यादा पसंद के साथ आया था, लेकिन क्या कोई बेहतर तरीका है?

नोट - मुझे एहसास है कि उत्परिवर्तनीय structs आमतौर पर बुराई है, लेकिन वे इस विशेष समस्या के लिए वास्तव में उपयोगी लगते हैं।

+0

क्या मैं पूछ सकता हूं कि जब आप इसे केवल 1 एकल मान निर्दिष्ट करते हैं तो ienumerable क्यों? – terrybozzio

+0

'गणना करें ब्लॉक्स' एक 'IENumerable >' –

उत्तर

6

बस अपने क्षेत्र को कन्स्ट्रक्टर में प्रारंभ करें।

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

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

यह निश्चित रूप से सही है। दुर्भाग्यवश अब मैं वास्तव में [इस समस्या] से परेशान हो रहा हूं (http://stackoverflow.com/q/4460206/644812), इसलिए मैं बस अपनी कस्टम संरचना का उपयोग कर सकता हूं। –

4

आप 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; 
    } 
} 
संबंधित मुद्दे