2011-01-19 14 views
28

में अपवाद मैंने इसके उत्तर के लिए एसओ के आसपास खोला है, और अब तक का सबसे अच्छा मुझे here है, हालांकि यह स्थिर रचनाकारों के उदाहरणों के लिए तैयार है; मैं केवल क्लासिक का उपयोग कर रहा हूं।स्थिर कन्स्ट्रक्टर

मेरे कोड:

public static class MailHelper { 

    private static string mailHost; 

    static MailHelper() { 

     var mailSettings = ConfigurationManager.GetSection("MailSettings") as NameValueCollection; 
     if (null == mailSettings) { 
      throw new ConfigurationErrorsException("Missing Mail Settings in the configuration file"); 
     } 

     mailHost = ConfigurationManager.AppSettings["mailHost"]; 
     if (null == mailHost) { 
      throw new ConfigurationErrorsException("Missing mailHost setting in the configuration file"); 
     } 

    } 

    public static void SendMail(MailMessage Message) { 
     ... 
    } 

} 


try { 
    MailHelper.SendMail(Message); 
} 
catch (ConfigurationErrorsException exc) { 
    ... 
} 

// ???  
MailHelper.SendMail(Message); 


. 

तो अगर स्थिर निर्माता एक अपवाद पहली बार यह कहा जाता है, क्या दूसरी बार मैं स्थिर SendMail() विधि तक पहुँचने का प्रयास होता है फेंकता है?

पीएस: क्षमा करें अगर आपको K& आर ब्रेस स्टाइल के स्ट्रॉस्ट्रप के संस्करण को पसंद नहीं है, लेकिन ब्रेसिज़ को अपनी पसंदीदा ऑलमैन शैली में बदलने के लिए मेरी पोस्ट को संपादित न करें। धन्यवाद।

+0

यह असफल होना चाहिए, लेकिन अपने लिए कोशिश करने में क्या गलत है? –

+0

मुझे नहीं लगता कि यह वास्तव में एक (स्थैतिक) कन्स्ट्रक्टर से फेंकने के लिए समझ में आता है, क्योंकि तब कक्षा एक अस्थिर स्थिति में है (पूरी तरह शुरू नहीं हुई)। एक स्पष्ट 'इनिट()' फ़ंक्शन जिसे आप उपयोग से पहले कॉल करते हैं, बनाने के बारे में (इसे पहले से शुरू होने पर कुछ भी नहीं करना चाहिए), और यदि यह अपवाद फेंकता है, * कक्षा * – Cameron

+0

पोंटस का उपयोग न करें> मैंने सोचा कि जॉन को कुछ चाहिए अधिक अंक:) –

उत्तर

22

अन्य दो जवाब आपके डायरेक्ट सवाल का अच्छा जवाब हैं - यहाँ एक metaanswer है कन्स्ट्रक्टर की बजाय, आबादी। IMHO, "कॉन्फ़िगर नहीं किया गया" कन्स्ट्रक्टर चरण में उन तत्वों के लिए एक वैध कॉन्फ़िगरेशन स्थिति है, केवल SendMail समय पर नहीं। यह इस पूरी समस्या को दूर करेगा।

+0

+1, दिलचस्प परिप्रेक्ष्य –

+1

जॉन ने वास्तव में मेरे प्रश्न का सबसे सही उत्तर दिया, लेकिन यह उत्तर मेरे पास एक बेहतर समाधान का प्रस्ताव है। –

81

एक बार एक प्रकार का प्रारंभकर्ता एक बार विफल हो गया है, यह कभी भी पुनः प्रयास नहीं किया जाता है। ऐपडोमेन के जीवनकाल के लिए यह प्रकार मर चुका है। (ध्यान दें कि यह सभी प्रकार के प्रारंभकर्ताओं के लिए सच है, न केवल स्थिर रचनाकारों के प्रकारों के लिए। प्रारंभिक अभिव्यक्तियों के साथ स्थैतिक चर के साथ एक प्रकार, लेकिन कोई स्थैतिक रचनाकार, प्रारंभिक निष्पादन निष्पादन के समय में सूक्ष्म अंतर प्रदर्शित नहीं कर सकता है - लेकिन यह अभी तक केवल एक बार होता है)

प्रदर्शन:।

using System; 

public sealed class Bang 
{ 
    static Bang() 
    { 
     Console.WriteLine("In static constructor"); 
     throw new Exception("Bang!"); 
    } 

    public static void Foo() {} 
} 

class Test 
{ 
    static void Main() 
    { 
     for (int i = 0; i < 5; i++) 
     { 
      try 
      { 
       Bang.Foo(); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine(e.GetType().Name); 
      } 
     } 
    } 
} 

आउटपुट:

In static constructor 
TypeInitializationException 
TypeInitializationException 
TypeInitializationException 
TypeInitializationException 
TypeInitializationException 

आप देख सकते हैं, स्थिर निर्माता केवल एक बार कहा जाता है।

+4

यह दिलचस्प है कि जब आप स्पष्ट रूप से 'अपवाद' फेंकते हैं तो आप केवल 'TypeInitializationExceptions' को पकड़ते हैं ... क्या यह' अपवाद 'निगल लिया जाता है? –

+7

@ जेम्स बी: नहीं, यह TypeInitializerException के InnerException में है। –

+0

आह! आशा है कि आपको बुरा लगेगा, मैंने क्रिस को जवाब दिया ... आपका प्रश्न वास्तव में उस प्रश्न का उत्तर देता है जो मैं पूछ रहा था और अपेक्षित व्यवहार को समझने में सबसे सहायक था, लेकिन मुझे अपने दृष्टिकोण के साथ समस्याओं से बचने के लिए अपना समाधान पसंद आया। कैचिंग TypeInitializationExceptions हर जगह मैं अपनी कक्षा में स्थिर कॉल करता हूं मजेदार नहीं लगता! आपकी सहायताके लिए धन्यवाद! –

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