2008-09-23 10 views
6

ठीक है, तो मैं एक भौहें उठाए गए निम्नलिखित समस्या में भाग गया।असेंबली। गेटकॉलिंगएस्परब्स() और स्थैतिक रचनाकार?

विभिन्न कारणों से मेरे पास एक परीक्षण सेटअप है जहां TestingAssembly.dll में परीक्षण कक्षाएं बेसटेस्टिंग Assembly.dll में टेस्टिंगबेज क्लास पर निर्भर करती हैं। बातें TestBase इस बीच में करता है में से एक अपनी ही में एक निश्चित एम्बेडेड संसाधन और बुला विधानसभा

तो मेरी BaseTestingAssembly निहित निम्नलिखित लाइनों के लिए देखो है ...

public class TestBase {  
    private static Assembly _assembly; 
    private static Assembly _calling_assembly; 

    static TestBase() { 
    _assembly = Assembly.GetExecutingAssembly(); 
    _calling_assembly = Assembly.GetCallingAssembly(); 
    } 
} 

स्टेटिक के बाद से मैं लगा , ये असेंबली आवेदन के जीवनकाल पर समान होंगी, इसलिए हर एक परीक्षण पर उन्हें पुन: गणना क्यों करें।

यह चलते समय मैंने देखा कि दोनों _assembly और _calling_assembly को क्रमशः बेसटेस्टिंग एस्क्रिप्ल्स और टेस्टिंग एस्क्रिप्ट के बजाय बेसटेस्टिंग एस्परब्स पर सेट किया जा रहा था।

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

उत्तर

5

स्थिर निर्माता है में मार डाला है पर कोई नियंत्रण नहीं है: मेरा सर्वोत्तम अनुमान क्योंकि है कि स्थिर निर्माता एक अप्रत्याशित संदर्भ से कहा जाता रहा है है रनटाइम द्वारा बुलाया जाता है और सीधे उपयोगकर्ता कोड द्वारा नहीं। आप इसे कन्स्ट्रक्टर में ब्रेकपॉइंट सेट करके और फिर डीबगर में चलकर देख सकते हैं। कॉल श्रृंखला में इसके ऊपर तुरंत कार्य मूल कोड है।

संपादित करें: ऐसे कई तरीके हैं जिनमें स्थिर प्रारंभकर्ता अन्य उपयोगकर्ता कोड की तुलना में एक अलग वातावरण में चलते हैं। कुछ अन्य तरीकों

  1. वे परोक्ष दौड़ की स्थिति multithreading
  2. आप प्रारंभकर्ता

सामान्य तौर पर बाहर से अपवाद नहीं पकड़ सकते से उत्पन्न से सुरक्षित रहते हैं हैं, यह शायद सबसे अच्छा उन्हें इस्तेमाल करने के लिए नहीं है कुछ भी परिष्कृत के लिए। आप निम्नलिखित पैटर्न के साथ एकल-इनिट लागू कर सकते हैं:

private static Assembly _assembly; 
private static Assembly Assembly { 
    get { 
    if (_assembly == null) _assembly = Assembly.GetExecutingAssembly(); 
    return _assembly; 
    } 
} 

private static Assembly _calling_assembly; 
private static Assembly CallingAssembly { 
    get { 
    if (_calling_assembly == null) _calling_assembly = Assembly.GetCallingAssembly(); 
    return _calling_assembly; 
    } 
} 

यदि आप बहुप्रचारित पहुंच की अपेक्षा करते हैं तो लॉकिंग जोड़ें।

+0

तो कॉलिंग असेंबली क्यों शून्य नहीं है? –

+0

क्या यह अधिक उपयोगी होगा? :) –

+0

नहीं, ऐसा लगता है कि यह समझ में आता है –

1

मुझे लगता है कि उत्तर C# static constructors की चर्चा में है।

उपयोगकर्ता जब स्थिर निर्माता कार्यक्रम

+0

वास्तव में आपके पास कुछ नियंत्रण है :) – leppie

1

असेंबली। गेटकॉलिंगएस्परब्स() कॉल कॉल में दूसरी प्रविष्टि की असेंबली देता है। यह इस बात पर निर्भर करता है कि आपकी विधि/गेटर/कन्स्ट्रक्टर कहां से कहा जाता है। मेरी लाइब्रेरी में नहीं है कि पहली विधि की असेंबली पाने के लिए मैंने पुस्तकालय में क्या किया है। (यह स्थिर रचनाकारों में भी काम करता है।)

private static Assembly GetMyCallingAssembly() 
{ 
    Assembly me = Assembly.GetExecutingAssembly(); 

    StackTrace st = new StackTrace(false); 
    foreach (StackFrame frame in st.GetFrames()) 
    { 
    MethodBase m = frame.GetMethod(); 
    if (m != null && m.DeclaringType != null && m.DeclaringType.Assembly != me) 
     return m.DeclaringType.Assembly; 
    } 

    return null; 
} 
संबंधित मुद्दे