2010-08-18 13 views
18

उत्पन्न करता है। CreateReCaptcha (यह HtmlHelper, स्ट्रिंग, स्ट्रिंग) ', ऑब्जेक्ट' <> g__initLocal0 'सभी अपवाद पथों के साथ डिस्पोजेक्ट नहीं किया गया है। कॉल सिस्टम। आईडीस्पोज़ेबल। ऑब्जेक्ट '<> g__initLocal0' पर सभी संदर्भों से पहले इसका संदर्भ दायरे से बाहर है।वस्तु initializers कोड विश्लेषण चेतावनी CA2000

 

    using (var control = new ReCaptchaControl() 
    { 
     ID = id, 
     Theme = theme, 
     SkipRecaptcha = false 
    }) 
    { 
     // Do something here 
    } 
 

मैं वस्तु initializers उपयोग नहीं करते हैं, कोड विश्लेषण खुश है:

 

    using (var control = new ReCaptchaControl()) 
    { 
     control.ID = id; 
     control.Theme = theme; 
     control.SkipRecaptcha = false; 

     // Do something here 
    } 
 

उन दो कोड ब्लॉक में क्या अंतर है

यहाँ कोड है? मैंने सोचा कि वे एक ही आईएल में परिणाम देंगे। या यह कोड विश्लेषण इंजन में एक बग है?

उत्तर

31

नहीं, कोई अंतर है।

एक ऑब्जेक्ट प्रारंभकर्ता केवल को के बाद निर्दिष्ट करता है सभी गुण सेट किए गए हैं। दूसरे शब्दों में, यह:

Foo tmp = new Foo(); 
tmp.Bar = "Baz"; 
Foo x = tmp; 

इसका मतलब है कि यदि संपत्ति setters की अपने मामले में एक अपवाद फेंक दिया, वस्तु निपटारा नहीं किया जाएगा:

Foo x = new Foo { Bar = "Baz" }; 

के बराबर है।

संपादित करें: जैसा कि मैंने सोचा था कि ... इस प्रयास करें:

using System; 

public class ThrowingDisposable : IDisposable 
{ 
    public string Name { get; set; } 

    public string Bang { set { throw new Exception(); } } 

    public ThrowingDisposable() 
    { 
     Console.WriteLine("Creating"); 
    } 

    public void Dispose() 
    { 
     Console.WriteLine("Disposing {0}", Name); 
    } 
} 

class Test 
{ 
    static void Main() 
    { 
     PropertiesInUsingBlock(); 
     WithObjectInitializer(); 
    } 

    static void PropertiesInUsingBlock() 
    { 
     try 
     { 
      using (var x = new ThrowingDisposable()) 
      { 
       x.Name = "In using block"; 
       x.Bang = "Ouch"; 
      } 
     } 
     catch (Exception) 
     { 
      Console.WriteLine("Caught exception"); 
     } 
    } 

    static void WithObjectInitializer() 
    { 
     try 
     { 
      using (var x = new ThrowingDisposable 
      { 
       Name = "Object initializer", 
       Bang = "Ouch" 
      }) 
      { 
       // Nothing 
      } 
     } 
     catch (Exception) 
     { 
      Console.WriteLine("Caught exception"); 
     } 
    } 
} 

आउटपुट:

Creating 
Disposing In using block 
Caught exception 
Creating 
Caught exception 

नोट कैसे कोई "निपटान ऑब्जेक्ट प्रारंभकर्ता" लाइन।

+1

यह समझ में आता है कि अब आप इसे लिखते हैं। आईएमओ यह एक गड़बड़ी है जिसे आसानी से अनदेखा किया जाता है। सौभाग्य से विजुअल स्टूडियो मुझसे ज्यादा बुद्धिमान है। – Tero

+1

@ जोन - तो यह निष्कर्ष निकालना सही है कि 'ऑब्जेक्ट प्रारंभकर्ता सिंटैक्स का उपयोग उस प्रकार के साथ न करें जो IDISposable लागू करता है'। (चूंकि सीए इंजन द्वारा ध्वजांकित मुद्दे को सही करने के लिए विस्तार हमारे नियंत्रण में नहीं है।) – Gishu

+2

@ गिशू: यदि आप सभी चिंतित हैं कि संपत्ति सेटर्स अपवाद फेंक सकते हैं, हां। –

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