2011-09-19 13 views
5

में आलसी लोडिंग प्रॉपर्टी में स्थैतिक स्थानीय चर का उपयोग मैंने हाल ही में वीबीएनईटी में स्थैतिक स्थानीय चर के उपयोगों के बारे में सीखा और आलसी लोडिंग गुणों में इसके संभावित उपयोग के बारे में सोचा।वीबीएनईटी

निम्नलिखित उदाहरण कोड पर विचार करें।

Public Class Foo 
    Implements IFoo 
End Class 

Public Interface IFoo 
End Interface 

Public Class Bar 

    Private _fooImplementation As IFoo 
    Public ReadOnly Property FooImplementation As IFoo 
    Get 
     If _fooImplementation Is Nothing Then _fooImplementation = New Foo 
     Return _fooImplementation 
    End Get 
    End Property 
End Class 

यह एक सामान्य, सरल बनाया आलसी लोडिंग संपत्ति होगी। आप एक ही व्यवहार के रूप में (जहां तक ​​मुझे पता है) पाने के लिए जेनेरिक आलसी कक्षा का भी उपयोग करना चाह सकते हैं।

अब, स्थैतिक चर का उपयोग करते समय संपत्ति को देखें।

Public Class Bar 

    Public ReadOnly Property FooImplementation As IFoo 
    Get 
     Static _fooImplementation as IFoo = New Foo 
     Return _fooImplementation 
    End Get 
    End Property 
End Class 

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

मेरा प्रश्न है: इनमें से कौन सा "सही" तरीका है? मुझे पता है कि स्थैतिक चर के अतिरिक्त ओवरहेड हैं, लेकिन क्या यह मेरी व्यक्तिगत राय में स्पष्ट रूप से खराब है, अस्पष्ट कोड जिसे दुरुपयोग किया जा सकता है? "पारंपरिक" विधि की तुलना में आप कितना प्रदर्शन खो देते हैं? विशाल कारखानों की तुलना में छोटे वर्गों के लिए यह कैसे मायने रखता है?

अग्रिम धन्यवाद।

उत्तर

3

स्टेटिक कीवर्ड के बजाय बहुत अधिक ओवरहेड है, संकलक इसे कार्यान्वित करने के लिए आईएल का एक बड़ा हिस्सा उत्पन्न करता है। यह करता है कि आपका पहला स्निपेट ऐसा नहीं करता है यह सुनिश्चित करता है कि थ्रेडिंग समस्याएं उत्पन्न नहीं करती है। यदि यह कोई चिंता नहीं है तो आपका पहला स्निपेट लॉट सस्ता है। न सिर्फ इसलिए कि इसमें बहुत कम आईएल है लेकिन यह भी क्योंकि यह रेखांकित किया जाएगा। स्टेटिक के साथ एक गेटर कभी भी रेखांकित नहीं किया जाएगा क्योंकि इसमें कोशिश/अंत कोड शामिल है।

यदि आप .NET 4 को लक्षित कर रहे हैं तो आपको निश्चित रूप से आलसी (टी) कक्षा में एक नज़र डालना चाहिए।

+0

+1 सहमत हैं, विशेष रूप से स्थिर स्थिरता को देखने के बाद। – tcarvin

+0

दूसरों के संदर्भ के लिए, [यहां एक और जवाब] (http://stackoverflow.com/a/12202349/4889167) हंस पासेंट से जो अधिक विस्तार से जाता है। –

1

यह सवाल मेरे लिए उत्तर खोजने के लिए काफी दिलचस्प था ... VB.NET वास्तव में स्थिर कैसे लागू करता है। यहां एक सी # समकक्ष है:

public class Bar 
    { 
    [SpecialName] 
    private IFoo \u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation; 
    [SpecialName] 
    private StaticLocalInitFlag \u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init; 

    public IFoo FooImplementation 
    { 
     get 
     { 
     Monitor.Enter((object) this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init); 
     try 
     { 
      if ((int) this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init.State == 0) 
      { 
      this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init.State = (short) 2; 
      this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation = (IFoo) new Foo(); 
      } 
      else if ((int) this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init.State == 2) 
      throw new IncompleteInitialization(); 
     } 
     finally 
     { 
      this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init.State = (short) 1; 
      Monitor.Exit((object) this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init); 
     } 
     return this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation; 
     } 
    } 

    [DebuggerNonUserCode] 
    public Bar() 
    { 
     this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init = new StaticLocalInitFlag(); 
    } 
    }