2009-09-02 19 views
15

उपयोग (...) कथन {} अंततः {} कोशिश करने के लिए वाक्य रचनात्मक चीनी है।कथन और कोशिश-पकड़() - अंततः पुनरावृत्ति का उपयोग करना?

लेकिन अगर मैं तो एक बयान का उपयोग कर नीचे की तरह है:

using (FileStream fs = File.Open(path)) 
{ 


} 

अब मैं अपवाद है कि इस फ़ाइल को खोलने का कारण बन सकता पकड़ने के लिए चाहते हैं (और यह काफी अधिक जोखिम कोड में है कि यह की वजह से असफल हो सकता है है पर्यावरण), लेकिन अगर मैं अंदर कोशिश करने की कोशिश करता हूं तो क्या पुनरावृत्ति नहीं होगी? जब कोड आईएल में संकलित हो जाता है, तो मुझे लगता है कि कोड JITted होने पर पुनरावृत्ति हटा दी जाएगी?

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

ऐसा लगता है कि मैं सीएलआर शायद अंदर क्या करता हूं इसके लिए बहुत बार दोहरा रहा हूं। क्या सीएलआर कैच क्लोज़ जोड़ता है?

मेरे सहयोगी ने तर्क दिया कि एक उपयोग कथन गन्दा है (लेकिन ऐसा इसलिए था क्योंकि मुझे एक पंक्ति बहुत मुश्किल थी क्योंकि मुझे उन्हें कोडिंग करना मुश्किल था क्योंकि मुझे उन्हें बहुत तेज़ी से बदलने की आवश्यकता थी और कोड के अन्य हिस्सों तक पहुंच नहीं थी आधार)। कहा गया है कि सहकर्मी उपयोग कथन का उपयोग नहीं करता है लेकिन क्या कभी भी उपयोग कथन के बीच कोई अंतराल अंतर है और आखिर में कोशिश करें/कोशिश करें-आखिरकार? मैंने इसका एक मामला देखा जहां डब्ल्यूसीएफ सेवाओं के अंत में और मूल्यों को वापस करने (आखिर में कुछ) का उपयोग करने के बारे में कोई ज्ञात कोने का मामला नहीं है। समाधान एक चेक ब्लॉक का उपयोग करना था। क्या सी # में ऐसा कुछ है?

एक और नोट पर, सभी प्रकार हैं जो अप्रबंधित संसाधनों के आईडीआईएसस्पेल मालिकों को लागू करते हैं? मेरे दोस्त के साथ एक चर्चा ने जवाब देने का जवाब दिया। (मैंने इस मंच के उपयोग खंड में कुछ धागे भी पढ़े हैं, कुछ अच्छे ज्ञान हैं)।

उत्तर

7

यदि आप वास्तव में चाहते हैं तो कुछ अपवादों को संभालने की आवश्यकता होने पर आप स्वयं को पैटर्न लागू कर सकते हैं। निजी तौर पर, मुझे अभी भी कोशिश/पकड़ ब्लॉक में उपयोग करने के लिए इसे सरल (और अधिक महत्वपूर्ण, स्पष्ट) लगता है।

लेकिन यदि आप इसे स्वयं करते हैं, तो सुनिश्चित करें कि आप इसे सही मानते हैं। Using ब्लॉक भी एक अनाम स्कोप ब्लॉक बनाता है ताकि आपका चरक संग्रह के लिए जल्द योग्य हो सके। .Dispose() विधि जो Using ब्लॉक के अंत में बुलाया गया है केवल अप्रबंधित संसाधनों को साफ़ करता है, और इसलिए आपकी ऑब्जेक्ट की कोई भी स्मृति थोड़ी देर तक लटका सकती है। यह एक बड़ी चिंता की संभावना नहीं है, लेकिन यह सिर्फ मामले में याद करने लायक है।

तो, पैटर्न का एक सीधा रूपांतरण करने के लिए, अपने कोड और अधिक इस तरह देखने के लिए की जरूरत है:

{ 
    FileStream fs; 
    try 
    { 
     fs = File.Open(path); 

    } 
    catch (FileNotFoundException e) { /* ... */ } 
    catch (IOException e) { /* ... */ } 
    catch (Exception e) {/* ... */} 
    finally 
    { 
     if (fs != null) fs.Dispose(); 
    } 
} 

व्यक्तिगत रूप से, मैं UsingCatch और Finally ब्लॉक का समर्थन करने के लिए विस्तारित होते देखना चाहते हैं। चूंकि वे पहले से ही कोड पर एक रूपांतरण कर रहे हैं, ऐसा प्रतीत नहीं होता है कि यह अतिरिक्त जटिलता को जोड़ देगा।

+0

अंत में समर्थन का समर्थन करता है हालांकि? अज्ञात स्कोप ब्लॉक का उपयोग करके, आप कहां उपयोग करने के बारे में पता लगाया? मैं इसके बारे में और जानना चाहता हूं। तो जब मैं एक प्रयोग ब्लॉक में फ़ाइल खोलता हूं (उदाहरण के लिए FileSream.Open()), यह अपवाद बबल हो जाएगा। यदि उपयोग कथन लागू/आखिरकार लागू करता है, तो मुझे पकड़ने के लिए कोशिश/पकड़ में लपेटना होगा। – dotnetdev

4

यदि आपको कथन के दौरान होने वाले विभिन्न असाधारण मामलों को स्पष्ट रूप से संभालने की आवश्यकता है, तो आप using को try/catch/finally के साथ प्रतिस्थापित कर सकते हैं और अंततः Dispose() पर कॉल कर सकते हैं। या आप निपटान सुनिश्चित करने से असाधारण परिस्थितियों को अलग करने के लिए using ब्लॉक के आसपास try/catch डाल सकते हैं।

केवल चीज using यह सुनिश्चित करता है कि निपटान() को ब्लॉक के अंदर एक अपवाद फेंकने के बावजूद भी कहा जाता है। यह सामान्य try/[catch]/finally संरचना का एक बहुत सीमित, अत्यधिक विशिष्ट कार्यान्वयन है।

महत्वपूर्ण बात यह है कि इनमें से किसी भी विकल्प का कोई वास्तविक प्रभाव नहीं है - जब तक आपको जो चाहिए वह पठनीय और समझने योग्य है, कौन परवाह करता है? यह एक अतिरिक्त प्रयास की तरह नहीं है एक बाधा या कुछ भी होगा!

अपने अंतिम प्रश्न का उत्तर देने के लिए - नहीं, आईडीस्पोजेबल निश्चित रूप से यह आवश्यक नहीं है कि कार्यान्वयनकर्ता अप्रबंधित संसाधनों को संभाला है। यह उससे कहीं अधिक सरल और अधिक सामान्य पैटर्न है। यहाँ एक उपयोगी उदाहरण है:

public class Timer : IDisposable 
{ 
    internal Stopwatch _stopwatch; 
    public Timer() 
    { 
     this._stopwatch = new Stopwatch(); 
     this._stopwatch.Start(); 
    } 

    public void Dispose() 
    { 
     this._stopwatch.Stop(); 
    } 
} 

हम स्पष्ट रूप से शुरू पर भरोसा करते हैं और का उपयोग करके बुलाया जा रहा है को रोकने के लिए बिना समय बातें करने में इसका उपयोग कर सकते हैं:

using(Timer timer = new Timer()) 
{ 
    //do stuff 
} 
4

का उपयोग करने और कोशिश-अंत में बीच सबसे बड़ा अंतर है कि उपयोग केवल Dispose() विधि को कॉल करेगा।यदि आप अपना खुद का अंततः ब्लॉक लागू करते हैं तो अन्य तर्क कर सकते हैं, उदाहरण के लिए लॉगिंग, जिसे उपयोग में शामिल नहीं किया जाएगा।

+0

+1 शॉर्टनेस –

7

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

जहां तक ​​IDISposable के बारे में आपका प्रश्न है: कोई भी इसे किसी भी कारण से लागू कर सकता है। अप्रबंधित संसाधनों तक सीमित होने के लिए कोई तकनीकी कारण नहीं है। (चाहे में अप्रबंधित संसाधनों तक सीमित हो, कोड एक अलग प्रश्न है)।

3

using निर्माण try/finally ब्लॉक के लिए शॉर्टेंड है। यही कारण है, संकलक उत्पन्न करता है:

FileStream fs = null; 
try 
{ 
    fs = File.Open(path); 
    // ... 
} 
finally 
{ 
    if (fs != null) 
     fs.Dispose(); 
} 

तो यह using उपयोग करने के लिए यदि आप एक catch की जरूरत नहीं है उचित है, लेकिन आप सिर्फ एक सामान्य try/catch/finally का उपयोग करना चाहिए अगर आप तब करते हैं।

+2

के लिए +1 'try'/'catch' में स्वयं का उपयोग करके लपेटने में कुछ भी गलत नहीं है। यह 'आखिरकार' से स्पष्ट है क्योंकि यह तुरंत स्पष्ट है कि ब्लॉक अंततः 'अंत में' देखने के बिना बाहर निकलता है। –

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