2010-05-12 14 views
10

मैं चर मैं एक का उपयोग कर बयान कथन का उपयोग अंदर में बनाने हूँ लौटने हूँ उपयोग करने के लिए इस्तेमाल किया चर वापसी (अजीब लगता है):अंदर सी # का उपयोग कर

public DataTable foo() 
{ 
    using (DataTable properties = new DataTable()) 
    { 
     // do something 
     return properties; 
    } 
} 

इस गुण चर निपटान करेंगे ??

चेतावनी 34 CA2000: Microsoft.Reliability:

इस बजे कर अभी भी इस चेतावनी मिलने के बाद विधि में 'test.test', सभी संदर्भों से पहले पर वस्तु 'गुण' System.IDisposable.Dispose फोन यह दायरे से बाहर हैं।

कोई विचार?

धन्यवाद

+3

, यह सिर्फ बुरा डिजाइन है और पर फिर से काम किया जाना चाहिए। –

उत्तर

10

आप इसे वापस करना चाहते हैं, तो आप यह एक using बयान में लपेट नहीं कर सकते, क्योंकि एक बार आप ब्रेसिज़ छोड़ देते हैं, यह क्षेत्र से बाहर चला जाता है और निपटारा हो जाता है।

आप इस तरह यह दृष्टांत करना होगा:

public DataTable Foo() 
{ 
    DataTable properties = new DataTable(); 
    return properties; 
} 

और उस पर Dispose() बाद में फोन।

+4

ऐसा लगता है कि 'foo() '==' GetUsefulDataTable() 'और' उपयोग 'ब्लॉक इस कार्य को कॉल करना चाहिए। –

3

हां। आप कोड ब्लॉक के अंत में डिस्प्ले नहीं करना चाहते हैं पर using कीवर्ड का उपयोग क्यों कर रहे हैं?

using कीवर्ड का उद्देश्य ऑब्जेक्ट का निपटान करना है।

http://msdn.microsoft.com/en-us/library/yh598w02.aspx

9

हाँ, यह यह निपटान होगा - और फिर इसे वापस जाएँ। यह लगभग हमेशा एक बुरी चीज है।

वास्तव में DataTable, Dispose के लिए लगभग कुछ भी नहीं करता है (अपवाद होने पर यह कहीं भी रिमोट किया गया है, लेकिन यह अभी भी एक आम विचार है। आम तौर पर आपको निपटान वस्तुओं को अनुपयोगी माना जाना चाहिए।

+0

तो, सीए 2000 चेतावनी ट्रिगर किए बिना किसी विधि से आईडीआईस्पोजेबल ऑब्जेक्ट को वापस करने के लिए सही पैटर्न क्या होगा? –

+0

@ जॉनी: मुझे नहीं पता, ईमानदार होने के लिए - मैंने इस तरह कोड विश्लेषण का उपयोग नहीं किया है। मुझे उम्मीद है कि चेतावनी दबाने के लिए कुछ रास्ता होगा। –

+0

@ झोनीडी.कैनो-वामवेयर- यदि आप तत्काल रूप से उन प्रश्नों को वापस लाने और वापस करने जा रहे हैं जिन्हें आपको स्पष्ट रूप से अपने कोड में निपटाने की आवश्यकता है। आपका कोड विश्लेषण "चुनना चाहिए" कि आप इसे कहीं और मैन्युअल रूप से निपटाना चाहते हैं। – IanNorton

3

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

यह ठीक काम करेगा।

public DataTable foo() 
{ 
    DataTable properties = new DataTable(); 
    // do something 
    return properties; 
} 
+0

अगर यह एक और अर्धविराम था तो यह ठीक काम करेगा। = पी – Jason

+0

टाइपो फिक्स्ड। – unholysampler

1

कीवर्ड का उपयोग का उपयोग कर अपने कोड का विस्तार करने के लिए:

{ 
    DataTable properties = new DataTable(); 
    try 
    { 
     //do something 
     return properties; 
    } 
    finally 
    { 
     if(properties != null) 
     { 
      ((IDisposable)properties).Dispose(); 
     } 
    } 
} 

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

7

माना जाता है कि यह एक फैक्ट्री विधि के लिए पैटर्न है जो एक डिस्पोजेबल ऑब्जेक्ट बनाता है।लेकिन, मैं अभी भी देखा है कोड विश्लेषण, भी इस बारे में शिकायत:

 Wrapper tempWrapper = null; 
     Wrapper wrapper = null; 

     try 
     { 
      tempWrapper = new Wrapper(callback); 
      Initialize(tempWrapper); 

      wrapper = tempWrapper; 
      tempWrapper = null; 
     } 
     finally 
     { 
      if (tempWrapper != null) 
       tempWrapper.Dispose(); 
     } 

     return wrapper; 

इस बात की गारंटी है कि अगर प्रारंभ विफल रहता है, वस्तु ठीक से निपटान किया जाता है, लेकिन अगर सब कुछ सफल होता है, एक विमुखता वाला उदाहरण विधि से दिया जाता है ।

एमएसडीएन आलेख: CA2000: Dispose objects before losing scope

+0

क्या यह मूल रूप से कैच ब्लॉक के बराबर नहीं है? आप 'रैपर एक्स = नल क्यों नहीं लिखेंगे; {{} पकड़ें {if (x! = null) x. कोशिश करें(); } '। इरादा केवल 100% अधिक स्पष्ट नहीं है, लेकिन अनावश्यक अस्थायी चर और मैन्युअल क्लीनअप से बचाता है। – Juliet

+0

मैं असहमत नहीं हूं। लेकिन मैंने हाल ही में खुद को देखा, क्योंकि मैं विफलता पर ऑब्जेक्ट का निपटान करने के बारे में चिंतित नहीं था, लेकिन क्योंकि मैं कोड पैटर्न खोजने की कोशिश कर रहा था जो सीए 2000 चेतावनी को खत्म कर देगा, बिना किसी विशेषता के इसे दबाए। कोड विश्लेषण प्रक्रिया विशेष रूप से यह देखने के लिए जांचती है कि नियम लागू होने की प्रकृति के कारण आखिरकार ब्लॉक में ऑब्जेक्ट का निपटारा किया गया है या नहीं। मुझे लगता है कि यह प्रश्न वास्तव में सीए 2000 के बारे में है, वस्तुओं का निपटान करने के बारे में नहीं। – Toby

+1

@ जुलिएट: 'पकड़' कथन में एक उथल-पुथल गायब है, और यहां तक ​​कि एक उथल-पुथल के साथ भी अर्थशास्त्र एक पकड़ नहीं है। अन्य चीजों के अलावा, यदि 'try' ब्लॉक में कुछ विधि' blah' को कॉल करने के लिए शामिल किया गया है जो अपवाद का कारण बन सकता है, तो कैच-एंड-रीथ्रो स्टैक ट्रेस को कॉल के बजाए रेथ्रो की लाइन संख्या दिखाने के लिए कारण बनता है। ब्लाह '(' ब्लाह 'के भीतर स्टैक ट्रेस सही होगा, लेकिन कॉल के लिए लाइन नंबर नहीं होगा)। – supercat

0

अन्य प्रतिक्रियाएं सही हैं: जैसे ही आप ब्लॉक का उपयोग करते हैं, आपकी ऑब्जेक्ट का निपटारा किया जाता है। यह सुनिश्चित करने के लिए उपयोग ब्लॉक बहुत अच्छा है कि किसी ऑब्जेक्ट को समय-समय पर निपटान किया जाता है, इसलिए यदि आप बाद में ऑब्जेक्ट को निपटाने के लिए अपने फ़ंक्शन के उपभोक्ताओं पर भरोसा नहीं करना चाहते हैं, तो आप इस तरह कुछ कोशिश कर सकते हैं:

public void UsingDataContext (Action<DataContext> action) 
{ 
    using (DataContext ctx = new DataContext()) 
    { 
     action(ctx) 
    } 
} 

इस तरह से आप की तरह कुछ कह सकते हैं: भले ही

var user = GetNewUserInfo(); 
UsingDataContext(c => c.UserSet.Add(user)); 
संबंधित मुद्दे