2010-10-14 10 views
14

निम्नलिखित कोड दो CA2000 चेतावनियां उत्पन्न करता है (दूसरों के बीच, लेकिन यह बात नहीं है)।स्वामित्व स्थानांतरित होने पर CA2000 चेतावनी से कैसे छुटकारा पाएं?

public sealed class Item: IDisposable 
{ 
    public void Dispose() {} 
} 

public sealed class ItemContainer 
{ 
    public void Add(Item item) 
    { 
    } 
} 

public sealed class Test: IDisposable 
{ 
    private ICollection<Item> itemCollection; 
    private ItemContainer itemContainer; 

    private void Add(Item item) 
    { 
     itemCollection.Add(item); 
    } 

    public void Initialize() 
    { 
     var item1 = new Item(); // no warning 
     itemCollection.Add(item1); 

     var item2 = new Item(); // CA2000: call Dispose on object item2 
     Add(item2); 

     var item3 = new Item(); // CA2000: call Dispose on object item3 
     itemContainer.Add(item3); 
    } 

    public void Dispose() {} 
} 

ध्यान दें कि आइटम 1 के लिए कोई चेतावनी उत्पन्न नहीं है। ऐसा लगता है, कोड विश्लेषण मानता है कि ICollection आइटम की ज़िम्मेदारी लेगा और अंत में इसका निपटान करेगा।

क्या मेरे Add विधियों को चिह्नित करने का कोई तरीका है, ताकि चेतावनी दूर हो जाए?

मैं CA1062 के लिए ValidatedNotNullAttribute के समान कुछ ढूंढ रहा हूं।

संपादित करें: इसे स्पष्ट करने के लिए: यह मेरा असली कोड नहीं है। असली कोड में, सब ठीक से निपटान किया जाता है।

यह सिर्फ इतना है कि सीए यह नहीं पहचानता कि मेरे Add विधियों को कॉल स्वामित्व स्थानांतरित करता है। मैं इसे अपने एड विधियों के साथ उसी तरह व्यवहार करना चाहूंगा जिस तरह से यह ICollection.Add का इलाज करता है।

उसी दायरे में निपटना एक विकल्प नहीं है।

उत्तर

6

मैं भी connect.microsoft.com पर इस पूछा और यह कि वे क्या जवाब है:

आप कंटेनर/संग्रह वस्तु कहते हैं कि डिस्पोजेबल वस्तु को लागू ICollection या ICollection < टी > होने से इस मुद्दे को वैकल्पिक हल कर सकते हैं । ऐड को करने वाली विधि में "एड" से शुरू होने वाला नाम भी होना चाहिए।

और निश्चित रूप से पर्याप्त: जब कक्षा परीक्षण आईसीओलेक्शन < आइटम > लागू करता है, तो चेतावनी दूर हो जाती है। मामले में मामले के लिए यह एक स्वीकार्य समाधान है। लेकिन यह अभी भी एक खुला प्रश्न है कि क्या करना है, जब स्वामित्व के हस्तांतरण को इंगित करने के लिए आईसीओलेक्शन लागू करना उचित नहीं है।

public sealed class Test: IDisposable, ICollection<Item> 
{ 
    public void Initialize() 
    { 
     var item1 = new Item(); // no warning 
     itemCollection.Add(item1); 

     var item2 = new Item(); // no warning 
     ((ICollection<Item>)this).Add(item2); 

     var item3 = new Item(); // no warning 
     AddSomething(item3); 
    } 

    //... implement ICollection and Method AddSomething 
} 
+0

मेरा स्वयं का जवाब स्वीकार किया गया, क्योंकि मैंने इस मामले में यही किया है: एक वर्ग पर आईसीओलेक्शन लागू करें जो पहले से ही IDISposable लागू किया गया है। मैं पूरी तरह से डेमियन से सहमत हूं: अगर सीए को आईडीस्पोजेबल और आईसीओलेक्शन दोनों की आवश्यकता होती है तो यह अधिक समझ में आ जाएगा। – Henrik

+0

क्या इंडेक्स द्वारा डिस्पोजेबल वस्तुओं के शब्दकोश पर कुछ समान करने का कोई तरीका है? – Dave

9

क्या आप कोड को ठीक करना चाहते हैं या चेतावनियों को दबाएं? चेतावनियों को दबाने से सीधा है:

[SuppressMessage("Microsoft.Reliability", 
       "CA2000:DisposeObjectsBeforeLosingScope", 
       Justification = "Your reasons go here")] 
public void Initialize() 
{ 
    // ... 
} 
+2

मैं इसे औचित्य के साथ देखना चाहूंगा और स्टाइलकॉप भी करूंगा। – annakata

+1

@annakata: और ऐसा ही होगा I इसे शामिल करने के लिए संपादित ... – LukeH

+1

मैं चेतावनी दबाने के लिए पसंद नहीं करना चाहूंगा। यदि विधि बाद में संशोधित की गई है, तो उपयुक्त होने पर, मैं एक चेतावनी प्राप्त करना चाहता हूं। – Henrik

1

निश्चित रूप से सबसे पहले करना है कि निपटान विधि संग्रह के सदस्यों को साफ करें। मुझे लगता है कि वास्तविक कोड की बजाय उदाहरण में सिर्फ एक त्रुटि है।

इसके अलावा, मैं चेतावनी को दबा दूंगा। मैं बहुत दृढ़ता से किसी भी दमन कि पकड़:

  1. , एक बहुत ही कम गुंजाइश का होना चाहिए तो यह चेतावनी है कि एक वास्तविक गलती है की एक अन्य मामले को दबाने नहीं है।
  2. किसी टिप्पणी के साथ टिप्पणी की जानी चाहिए, इससे कोई फर्क नहीं पड़ता कि मस्तिष्क-मृत कैसे स्पष्ट लगता है कि चेतावनी दबाने के लिए सुरक्षित है।

यह कहा गया है कि, मुझे लगता है कि सीए 2000 का विश्लेषण इतना खराब है क्योंकि इसे डिफ़ॉल्ट रूप से चेक करने के लायक नहीं है, बल्कि केवल कभी-कभी समीक्षाओं में भी। झूठी-सकारात्मक संख्याओं की एक निश्चित संख्या के बाद एक चेतावनी को अब भी चेतावनी नहीं माना जा सकता है, केवल शोर जो असली चेतावनियों को छुपा रहा है और इसलिए कोड को बग्गी होने की अधिक संभावना है।

6

मुझे पता है कि यह नमूना कोड है, और इसलिए यह कामकाज आपके असली कोड में काम करेगा, मैं नहीं कह सकता था।

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

public void Initialize() 
{ 
    var item1 = new Item(); // no warning 
    itemCollection.Add(item1); 

    var item2 = CreateItem(); // CA2000 no longer appears 
    Add(item2); 

    var item3 = new Item(); // CA2000: call Dispose on object item3 
    itemContainer.Add(item3); 
} 

private Item CreateItem() 
{ 
    return new Item(); 
} 

जाहिर है, CreateItem विधि भी भेजी जा सकती आर्बिट्ररी पैरामीटर आइटम निर्माता को पारित करने के लिए।

संपादित

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

+0

लेकिन इस मामले में, चेतावनी दिखाई नहीं देगी, भले ही जोड़ें (item2) हटा दिया गया हो और item2 को सत्यापित नहीं किया गया हो। इसलिए मैं चेतावनी को दबा सकता हूं। – Henrik

+0

@ हेनरिक - जितना अधिक समय मैं इसे देखता हूं, उतना ही उलझन में मिलता है। इस बात की कोई गारंटी नहीं है कि कोई विशेष आईसीओलेक्शन कार्यान्वयन सही तरीके से इसमें शामिल वस्तुओं का निपटान करेगा, इसलिए मैं सोच रहा हूं कि हम आइटम 1 के लिए CA2000 क्यों नहीं प्राप्त कर रहे हैं। –

+0

ने इस उत्तर को बक्षीस दिया। यह उस मामले में उपयोगी हो सकता है जहां CreateItem विधि ने आइटम को एक संग्रह में आंतरिक रूप से जोड़ा है ताकि यह सुनिश्चित किया जा सके कि यह निपटाया गया है। – Henrik

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