2010-08-18 26 views
18

。 CreateReCaptcha(this HtmlHelper,string,string)',對象'<> g__initLocal0'不會沿着所有異常路徑處理。調用System.IDisposable.Dispose對象'<> g__initLocal0'之前,所有對它的引用超出範圍。對象初始如果我使用對象初始使用塊,我得到代碼分析警告有關不正確處理的對象生成代碼分析警告CA2000

下面是代碼:

 

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

如果我不使用對象初始化,代碼分析是高興:

 

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

     // Do something here 
    } 
 

是什麼這兩個代碼塊之間的區別?我認爲他們會導致相同的IL。或者這是代碼分析引擎中的一個錯誤?

回答

31

不,這是有區別的。

對象初始值設定項只在之後指定給變量所有屬性都已設置。換句話說,這樣的:

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

等同於:

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

這意味着,如果物業制定者之一,在你的情況下拋出異常,對象不會被佈置。

編輯:由於我以爲......試試這個:

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

現在你寫出來了。海事組織這是一個容易被忽視的陷阱。幸運的是Visual Studio比我更聰明。 – Tero 2010-08-18 17:57:38

+1

@Jon - 因此,推斷'不要使用對象初始值設定項語法和一個也實現IDisposable的類型'是正確的。 (由於擴展不在我們的控制範圍內,因此無法解決由CA引擎標記的問題。) – Gishu 2014-01-21 12:15:25

+2

@Gishu:如果您擔心屬性設置者可能會拋出異常,那麼是的。 – 2014-01-21 13:34:16

相關問題