2016-01-26 10 views
5

मैं स्थिर रचनाकारों की आवश्यकता को समझने की कोशिश कर रहा हूं। मुझे मिली कोई भी जानकारी मेरे पास निम्नलिखित प्रश्न का उत्तर नहीं दिया गया है। के रूप में इसस्थिर रचनाकारों को समझने की कोशिश

class SimpleClass 
{ 
    // Static variable that must be initialized at run time. 
    static readonly long baseline = DateTime.Now.Ticks; 

    // Static constructor is called at most one time, before any 
    // instance constructor is invoked or member is accessed. 
    //static SimpleClass() 
    //{ 

    //} 
} 

करने का विरोध क्यों आप इस

class SimpleClass 
{ 
    // Static variable that must be initialized at run time. 
    static readonly long baseline; 

    // Static constructor is called at most one time, before any 
    // instance constructor is invoked or member is accessed. 
    static SimpleClass() 
    { 
     baseline = DateTime.Now.Ticks; 
    } 
} 

करना होगा?


यह अन्य प्रश्नों की नकल नहीं है, यह स्थिर रचनाकारों के बारे में है जो पैरामीटर स्वीकार नहीं करते हैं।

+0

यह स्थिर विशिष्ट प्रश्न नहीं है, प्रश्न गैर स्थैतिक प्रारंभिकरण के लिए भी मान्य है। –

+0

संभावित डुप्लिकेट [कन्स्ट्रक्टर में या घोषणा में कक्षा फ़ील्ड शुरू करें?] (Http://stackoverflow.com/questions/24551/initialize-class-fields-in-constructor-or-at-declaration) –

+0

@CyrilGandon यह नहीं है एक डुप्ली - यह स्थिर रचनाकारों के बारे में है जो पैरामीटर स्वीकार नहीं करते हैं। डुप्लिक टैग को हटाने पर विचार करें। –

उत्तर

5

आवश्यकता किसी भी तरह से स्पष्ट है: आप अपने स्थिर सदस्यों के लिए कुछ फ़ील्ड प्रारंभिक से अधिक करना चाहते हैं।

तार्किक रूप से यदि आप इस वर्ग के होते हैं:

class SimpleClass 
{ 
    // Static variable that must be initialized at run time. 
    static readonly long baseline = DateTime.Now.Ticks; 


} 

आप फिर से लिख सकते हैं यह एक ही प्रभाव है:

class SimpleClass 
{ 
    // Static variable that must be initialized at run time. 
    static readonly long baseline; 

    static SimpleClass() { 
     baseline = DateTime.Now.Ticks; 
    } 
} 

लेकिन बजाय, आप इस तरह के रूप में अपने स्थिर निर्माता में और अधिक कर सकता है निरीक्षण करने के लिए उन्हें (प्रतिबिंब का उपयोग कर) कुछ गुण और emiting कुछ तेजी से accessors/टिककर खेल, या सिर्फ सरल अन्य प्रणालियों अपने प्रकार बनाया गया है कि, आदि

जम्मू से सूचित सी # पुस्तक के माध्यम से effrey रिक्टर CLR:

जब सी # संकलक स्थिर फ़ील्ड का उपयोग इनलाइन प्रारंभ (BeforeFieldInit वर्ग) के साथ एक वर्ग देखता है, संकलक BeforeFieldInit मेटाडाटा ध्वज के साथ वर्ग के प्रकार परिभाषा तालिका प्रविष्टि का उत्सर्जन करता है । जब सी # कंपाइलर एक स्पष्ट प्रकार कन्स्ट्रक्टर (सटीक वर्ग) वाले वर्ग को देखता है, तो संकलक कक्षा के प्रकार परिभाषा तालिका प्रविष्टि को पहले FieldInit मेटाडेटा ध्वज के बिना उत्सर्जित करता है। इसके पीछे तर्क इस प्रकार है: स्थिर फ़ील्ड का प्रारंभिकरण फ़ील्ड तक पहुंचने से पहले किया जाना आवश्यक है, जबकि एक स्पष्ट प्रकार कन्स्ट्रक्टर में मनमानी कोड हो सकता है जिसमें दुष्प्रभाव हो सकते हैं; इस कोड को एक सटीक समय पर चलाने की आवश्यकता हो सकती है।

Obviouselly वहाँ पर्दे के पीछे हो रहा से ज्यादा कुछ है, मैं सी # के माध्यम से CLR से पूरा अध्याय को पढ़ने के लिए सुझाव है: "प्रकार कंस्ट्रक्टर्स"

+5

वैसे, वे काफी समान नहीं हैं - एक स्थिर कन्स्ट्रक्टर वाले वर्ग में कक्षा के मुकाबले अलग-अलग प्रारंभिक समय हो सकता है जिसमें केवल स्थिर क्षेत्र प्रारंभकर्ता होते हैं। देखें http://csharpindepth.com/Articles/General/Beforefieldinit.aspx –

+0

क्या आप उदाहरण दिखा सकते हैं कि मुझे स्थिर कन्स्ट्रक्टर की आवश्यकता क्यों है, मैं वहां क्या कर सकता हूं मैं फील्ड प्रारंभिकरण में नहीं कर सकता? –

+0

@ जोनस्केट शायद आप –

3

यह एक संभव अंतर का एक उदाहरण है:

class SimpleClass 
{ 
    static readonly long A = DateTime.Now.Ticks; 
    static readonly long B = DateTime.Now.Ticks; 

    static SimpleClass() 
    { 
    } 
} 

A और B, एक ही मूल्य होने की गारंटी नहीं कर रहे हैं, हालांकि, अगर आप निर्माता में लिखने के लिए गए थे, आप इसे की गारंटी दे सकें:

class SimpleClass 
{ 
    static readonly long A; 
    static readonly long B; 

    static SimpleClass() 
    { 
     var ticks = DateTime.Now.Ticks; 
     A = ticks; 
     B = ticks; 
    } 
} 

इसके अलावा, स्थिर सदस्यों के तत्काल के लिए आदेश जारी करता है।एक वर्ग घोषणा की

स्थिर क्षेत्र चर initializers कि शाब्दिक क्रम में क्रियान्वित कर रहे हैं कार्य की एक दृश्य है जिसमें वे में प्रदर्शित करने के अनुरूप:

स्थिर क्षेत्र आरंभीकरण के बारे में ECMA-334 के अनुसार

कक्षा घोषणा। यदि स्थिर कन्स्ट्रक्टर (§17.11) कक्षा में मौजूद है, तो निष्पादन स्थिर क्षेत्र प्रारंभकर्ता स्थैतिक कन्स्ट्रक्टर निष्पादित करने से ठीक पहले होता है।

class SimpleClass 
{ 
    public static readonly long A = IdentityHelper.GetNext(); 
    public static readonly long B = IdentityHelper.GetNext(); 

    static SimpleClass() 
    { 
    } 
} 

public static class IdentityHelper 
{ 
    public static int previousIdentity = 0; 
    public static int GetNext() 
    { 
     return ++previousIdentity; 
    } 
} 

: अन्यथा, स्थिर क्षेत्र initializers उस वर्ग के एक स्थिर क्षेत्र

तो का पहला प्रयोग करने से पहले एक कार्यान्वयन पर निर्भर समय पर क्रियान्वित कर रहे हैं, हम कुछ इस तरह लिख सकते हैं यहां, AB से पहले असाइन किए जाने की गारंटी है। इस उदाहरण में, A1 होगा, और B2 होगा। हम गारंटी दे सकते हैं कि A < B (माना जाता है कि पहचान अधिक नहीं है और थ्रेडिंग के साथ कोई समस्या नहीं है)। अब, अगर हम फिर से आदेश क्षेत्रों:

public static readonly long B = IdentityHelper.GetNext(); 
public static readonly long A = IdentityHelper.GetNext(); 

कार्यक्षमता बदल जाता है। इस प्रकार, हमने एक दुष्प्रभाव बनाया है जो फ़ील्ड परिभाषाओं को फिर से व्यवस्थित करके तुरंत स्पष्ट नहीं होता है।

एक अधिक होने की संभावना परिदृश्य है, हम ऐसा करना चाहते हो सकता है:

class SimpleClass 
{ 
    public static readonly long A = IdentityHelper.GetExpensiveResult().A; 
    public static readonly long B = IdentityHelper.GetExpensiveResult().B; 

    static SimpleClass() 
    { 
    } 
} 

यहाँ, हम क्षेत्रों के बीच GetExpensiveResult() साझा नहीं कर सकते।

+0

कोड है कि प्रश्न, 'लौट ++ currentIdentity' बेहतर है से संबंधित नहीं की एक छोटी जगह है, अन्यथा आप हमेशा होगा' IdentityHelper.currentIdentity == IdentityHelper.GetNext() ' –

+0

@DannyChen आप सही हैं - धन्यवाद:) – Rob

+0

@ डैनी चेन, क्या आप अपनी आखिरी टिप्पणी पर विस्तार कर सकते हैं; मुझे पूरा यकीन नहीं है कि मैं समझता हूं कि यह कैसे काम करता है –

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