2010-04-22 10 views
10

में बेस कन्स्ट्रक्टर के पास ऑब्जेक्ट संदर्भ पास करने के लिए मुझे चेतावनी मिलती है जब मैं विजुअल स्टूडियो के कोड विश्लेषण उपयोगिता के माध्यम से कुछ कोड चलाता हूं जो मुझे नहीं पता कि कैसे हल किया जाए। शायद यहां कोई भी इसी तरह के मुद्दे पर आया है, इसे हल किया है, और अपनी अंतर्दृष्टि साझा करने के लिए तैयार है।CA2000 सी #

मैं डेटाग्रिड व्यू नियंत्रण में उपयोग किए जाने वाले कस्टम-पेंट सेल का प्रोग्रामिंग कर रहा हूं। कोड जैसा दिखता है:

CA2000:

public class DataGridViewMyCustomColumn : DataGridViewColumn 
{ 
    public DataGridViewMyCustomColumn() : base(new DataGridViewMyCustomCell()) 
    { 
    } 

यह निम्न चेतावनी उत्पन्न Microsoft.Reliability: विधि में 'DataGridViewMyCustomColumn.DataGridViewMyCustomColumn()' वस्तु 'पर नया DataGridViewMyCustomCell System.IDisposable.Dispose फोन() 'इससे ​​पहले कि सभी संदर्भ दायरे से बाहर हैं।

मैं समझता हूँ कि यह मेरे चेतावनी है DataGridViewMyCustomCell (या एक वर्ग है कि यह से विरासत) IDisposable इंटरफ़ेस और निपटान() विधि जब यह नहीं रह गया है DataGridViewMyCustomCell ने दावा किया है किसी भी संसाधनों को साफ करने के बुलाया जाना चाहिए लागू करता है।

इंटरनेट पर मैंने जो उदाहरण देखे हैं, वे ऑब्जेक्ट के जीवनकाल को गुंजाइश करने के लिए ब्लॉक का उपयोग करते हैं और सिस्टम को स्वचालित रूप से इसका निपटान करते हैं, लेकिन जब कन्स्ट्रक्टर के शरीर में स्थानांतरित हो जाता है तो आधार पहचाना नहीं जाता है, इसलिए मैं ' टी इसके चारों ओर एक ब्लॉक ब्लॉक लिखो ... जो मुझे यकीन नहीं है कि मैं वैसे भी करना चाहता हूं, क्योंकि वह ऑब्जेक्ट को मुक्त करने के लिए रन टाइम को निर्देश नहीं देगा जो बाद में बेस क्लास के अंदर उपयोग किया जा सकता है?

मेरा प्रश्न तब है, क्या कोड ठीक है? या, चेतावनी को हल करने के लिए इसे कैसे बदला जा सकता है? मैं चेतावनी को दबाना नहीं चाहता हूं जब तक कि ऐसा करने के लिए वास्तव में उचित नहीं है।

उत्तर

18

यदि आप विजुअल स्टूडियो 2010 का उपयोग कर रहे हैं तो CA2000 पूरी तरह टूटा हुआ है। यह FxCop (ए.के.ए. कोड विश्लेषण) के अन्य संस्करणों में भी टूटा जा सकता है, लेकिन वीएस -2010 एकमात्र ऐसा है जिसे मैं देख सकता हूं। हमारे codebase इस तरह कोड के लिए CA2000 चेतावनी दे रहा है ...

internal static class ConnectionManager 
{ 
    public static SqlConnection CreateConnection() 
    { 
     return new SqlConnection("our connection string"); 
    } 
} 

... यह दर्शाता है कि कनेक्शन निपटारा किया जा रहा है इससे पहले कि यह विधि में क्षेत्र से बाहर चला जाता है। खैर, हाँ, यह सच है, लेकिन आवेदन के लिए यह के दायरे से बाहर नहीं है क्योंकि यह कॉलर पर वापस आ गया है - यह विधि का पूरा बिंदु है! इसी तरह, आपका कन्स्ट्रक्टर तर्क दायरे से बाहर नहीं जा रहा है लेकिन बेस क्लास को पास किया जा रहा है, इसलिए यह वास्तविक समस्या के बजाय नियम से झूठा सकारात्मक है।

यह एक उपयोगी नियम होता था, लेकिन अब आप वास्तव में ऐसा कर सकते हैं जब तक कि वे इसे ठीक न करें। जो दुर्भाग्यपूर्ण है, क्योंकि (बहुत कम) वास्तविक सकारात्मक चीजें हैं जिन्हें ठीक किया जाना चाहिए।

+3

+1 'पूरी तरह से वीएस 10 में टूटा' के लिए +1। लोगों को मुझे कोड-गुणवत्ता-सुधार की सवारी पर शामिल होने के लिए राजी करना बहुत मुश्किल है जब उपकरण मुझे इतना बेवकूफ लगते हैं ... –

0

धन्यवाद, ग्रेग। यह मेरी चिंता है - कुछ सकारात्मक जो तय किया जाना चाहिए। खैर, शायद वीएस के अगले पुनरावृत्ति में यह अधिक सटीक होगा। मैं अब के लिए कोड में चेतावनी को दबा दूंगा।

+0

मैंने अपने कोड में निम्नलिखित दमन डाला: '[System.Diagnostics.CodeAnalysis.SuppressMessage (" माइक्रोसॉफ्ट विश्वसनीयता "," सीए 2000: गुंजाइश खोने से पहले वस्तुओं का निपटान करें। यह एक टूटा हुआ नियम है। Http://stackoverflow.com/q/2687398/228059 अधिक के लिए देखें ")] – noonand

+0

या आप एक .ruleset फ़ाइल बना सकते हैं, चुनें कौन से नियम आप रखना चाहते हैं और समाधान गुणों में बिल्ड प्रकारों को जोड़ना चाहते हैं। यहां [एक उदाहरण] है (https://github.com/madskristensen/WebEssentials2013/blob/master/EditorExtensions/CodeAnalysis.ruleset)। डिफ़ॉल्ट रूप से, वीएस .ruleset फ़ाइल के लिए चेकबॉक्स के साथ एक डिज़ाइन मोड संपादक खोल देगा। –

1

एक श्रृंखलित निर्माता, आधार निर्माता के लिए एक नया IDisposable वस्तु पारित के बाद से यह try finally ब्लॉक के किसी भी प्रकार में श्रृंखलित निर्माता कॉल रैप करने के लिए संभव नहीं है, जैसा कि आप ध्यान दें करने के लिए कोई सुरक्षित और सुरुचिपूर्ण तरीका नहीं है।वहाँ एक दृष्टिकोण है जो सुरक्षित है, लेकिन यह शायद ही सुरुचिपूर्ण है:

protected DataGridViewMyCustomColumn(ref IDisposable cleaner) : 
    base(storeAndReturn(ref cleaner, new DataGridViewMyCustomCell())) 
{ 
} 

कोड जो एक नई वस्तु तो होता जरूरत:

internal static TV storeAndReturn<TR,TV>(ref TR dest, TV value) where TV:TR 
{ 
    dest = value; return value; 
} 

की तरह निर्माता नज़र कुछ है: की तरह एक उपयोगिता विधि कुछ को परिभाषित एक सार्वजनिक स्थैतिक फैक्ट्री विधि को कॉल करने के लिए जो try/finally ब्लॉक के भीतर उचित कन्स्ट्रक्टर को कॉल करेगा, जिसका मुख्य लाइन cleaner को समाप्त होने से ठीक पहले बाहर कर देगा, और जिसका finally ब्लॉक पर cleaner पर कॉल करेगा शून्य नहीं है बशर्ते कि प्रत्येक उप-वर्ग एक समान फैक्ट्री विधि को परिभाषित करता है, यह दृष्टिकोण यह सुनिश्चित करेगा कि नया IDisposable ऑब्जेक्ट डिस्प्ले हो जाएगा, भले ही अपवाद उस समय के बीच होता है जब एन्सेपुलटिंग ऑब्जेक्ट क्लाइंट कोड के संपर्क में आता है। पैटर्न बदसूरत है, लेकिन मुझे यकीन नहीं है कि कोई अच्छा अन्य पैटर्न शुद्धता सुनिश्चित करेगा।