2011-01-06 12 views
8

मैं वर्तमान में क्लासिक कन्स्ट्रक्टर से आलसी प्रारंभिक गुणों में महंगी प्रारंभिकता के रूप में स्थानांतरित करने के लिए व्यापक रूप से उपयोग की जाने वाली कक्षा में बदलाव कर रहा हूं।गुणों के साथ आलसी प्रारंभिकरण के लिए तरीके

से पहले::

public class ClassA 
{ 
    public readonly ClassB B; 

    public void ClassA() 
    { 
     B = new ClassB(); 
    } 
} 

के बाद:

public class ClassA 
{ 
    private ClassB _b; 

    public ClassB B 
    { 
     get 
     { 
      if (_b == null) 
      { 
       _b = new ClassB(); 
      } 

      return _b; 
     } 
    } 
} 

कक्षा मैं फेरबदल कर रहा हूँ में इन गुणों का एक उचित कुछ और हैं, और कुछ नीचे (ग # में) एक उदाहरण है कुछ संदर्भों में उपयोग नहीं किया जाता है (इसलिए आलस्य), लेकिन यदि उनका उपयोग किया जाता है तो उन्हें बार-बार कहा जाने की संभावना है।

दुर्भाग्यवश, संपत्तियों का अक्सर कक्षा के अंदर भी उपयोग किया जाता है। इसका मतलब यह है कि बिना किसी विधि के निजी विधि (_b) का उपयोग सीधे किसी विधि द्वारा किया जा सकता है।

क्या कक्षा के अंदर केवल सार्वजनिक संपत्ति (बी) उपलब्ध कराने का एक तरीका है, या एक ही प्रारंभिक समय के साथ एक वैकल्पिक विधि भी आवश्यक है?

यह (नहीं पर्याप्त जाहिरा तौर पर व्यक्तिपरक) प्रोग्रामर्स से फिर से पोस्ट किया जाता है: https://softwareengineering.stackexchange.com/questions/34270/best-methods-for-lazy-initialization-with-properties

+0

@ चतुरता: –

उत्तर

6

बैकिंग चर के लिए सीधे पहुंच से बचने के लिए आप आलसी गुणों को बेस क्लास में धक्का देने पर विचार कर सकते हैं। आदर्श नहीं मैं जानता हूँ। मैंने हमेशा सोचा है कि सी # यानी आलसी गुणों के लिए प्रत्यक्ष समर्थन में कुछ कमी आई थी।

+0

यह अच्छा होगा अगर आप इस ज़रूरत को दूर करने के लिए आलसी बनाने के लिए एक संपत्ति का श्रेय दे सकते हैं और इसके संदर्भ में बिना आलसी लोड किए गए गुणों को संदर्भित कर सकते हैं। वैल्यू। – BenAlabaster

+0

@BenAlabaster जब मैंने पहली बार स्वचालित गुणों को देखा तो मैंने सोचा कि उन्होंने आलसी क्षमता को जोड़ा है - दुर्भाग्य से नहीं। प्रारंभिक फंक्शन के साथ स्वचालित संपत्ति को परिभाषित करने में सक्षम होना बहुत अच्छा होगा। –

+0

@ चिंतनशील रोचक विचार, मुझे आश्चर्य है कि क्या यह प्राप्त होगा ... खेलना शुरू करने का समय;) – BenAlabaster

16

खैर, मेरी सिफारिश समाधान संपत्ति, नहीं क्षेत्र का उपयोग करने के अपने सहकर्मी को बताने के लिए किया जाएगा। लेकिन बेवकूफ प्रूफ सकता है इसे इस तरह कुछ हद तक:

public class ClassA 
{ 
    private Lazy<ClassB> _b = new Lazy<ClassB>(() => new ClassB()); 

    public ClassB B 
    { 
     get 
     { 
      return _b.Value; 
     } 
    } 
} 

अब यह बहुत ऊपर पेंच करना मुश्किल है।

+0

+1 के लिए धन्यवाद। यह वही था जो मैं सुझाव देने वाला था। –

+0

इस उदाहरण में 'आलसी ' वास्तव में क्या है? धन्यवाद। –

+0

अच्छा, मुझे आलसी कक्षा से अवगत नहीं था; हालांकि यह 4 में नया दिखाई देता है, यह सुनिश्चित नहीं है कि ओपी क्या उपयोग कर रहा है। –

3

@chibacity पोस्ट (और बाद में) हटा दिया गया [और बाद में हटाया गया: पी] एक सार आधार वर्ग का उपयोग कर एक वैकल्पिक विकल्प। हालांकि यह कोड वितरण के मामले में आदर्श नहीं हो सकता है, यह एक क्लीनर और अधिक संक्षिप्त कक्षा के लिए बहुत सारे कोड अव्यवस्था को हटाने के लिए एक अच्छा encapsulation प्रदान करता है। उदाहरण के लिए, आप तकनीक के संयोजन दोनों लक्ष्यों को प्राप्त करने पर विचार कर सकते:

public class ClassB { /* Class to be lazily instantiated */ } 

public abstract class BaseA 
{ 
    private Lazy<ClassB> _b = new Lazy<ClassB>(() => new ClassB()); 
    public virtual ClassB B { get { return _b.Value; } } 
} 

public class ClassA : BaseA 
{ 
    public override ClassB B { get { return base.B; } } 
} 

पहली नज़र में, ऐसा लगता है जैसे यह अधिक घना है, लेकिन जब आप उस ClassA पर विचार जो वर्ग आप में काम किया जाएगा और इसके साथ, अब इसका मतलब है कि आपके सभी संदर्भ एक ही संपत्ति के माध्यम से जा रहे हैं - कोई अपरिहार्य अनावश्यक क्षेत्र संभावित भ्रम पैदा नहीं कर रहा है, संपत्ति को _b को संदर्भित करने के लिए कोई बाईपास नहीं है और आपके सहकर्मी को यह बताने की कोई आवश्यकता नहीं है ... केवल एक।

यह नहीं कह रहा कि यह ऐसा करने का सही तरीका है या यह एक ऐसा पैटर्न है जिसे पालन किया जाना चाहिए या नहीं किया जाना चाहिए, मैं केवल @ चिबासिटी के सुझावों को इंगित कर रहा हूं जो अन्यथा ध्यान न दें।

यह अच्छा होगा अगर आप बीवीएलयू को संदर्भित किए बिना आलसी लोड किए गए गुणों को निहित कर सकें ...उदाहरण के लिए: parameterless कंस्ट्रक्टर्स बिना

[Lazy] 
public ClassB B { get; } 

या के लिए वस्तुओं

[Lazy(() => new ClassB("Hello", "World"))] 
public ClassB B { get; } 

या शायद @chibacity एक टिप्पणी

public ClassB B { lazyget; } 

या

public ClassB B { lazyget : new ClassB(); } 

आह में सुझाव के रूप में, मैं इनमें से कोई भी मत सोचो वर्तमान में किसी भी रूप में समाधान उपलब्ध हैं ...

+0

मुझे func और विशेषता के साथ वाक्यविन्यास पसंद है, लेकिन दुर्भाग्यवश विशेषता तर्कों को संकलित-समय स्थिर होना चाहिए, इसलिए यह बाहर दिखता है - अच्छा लगता है। :) –

+0

@ चतुरता यह एक बात है जब मैं एपीआई लिख रहा हूं, मैं हमेशा के बारे में सचेत हूं - जब मैं इसे कॉल कर रहा हूं या इस सुविधा का उपयोग कर रहा हूं तो मैं सिंटैक्स को कैसे देखना चाहूंगा? आमतौर पर मैं डिज़ाइन करता हूं कि मैं अपनी एपीआई डिज़ाइन करने से पहले अपनी कॉल देखना चाहूंगा ताकि सब कुछ ठीक हो। – BenAlabaster

संबंधित मुद्दे