簡體   English   中英

一個 using 塊,在構造函數中有一個 object 初始化塊

[英]A using block, with an object initializer block in the constructor

如果您從using 語句調用構造函數,則會自動處理 object 並用 try/catch 塊包裝它。 那是構造函數中的 object 初始化程序塊。

但是在同一語句中初始化的成員類型會變成什么? 例如:

  class TypeThatThrowsAnException 
  {
       public TypeThatThrowsAnException() 
       {
           throw new Exception();
       }
  }

  using (SomeDisposable ds = new SomeDisposable() {
       MemberThatThrowsAnException m = new TypeThatThrowsAnException()
  })
  {
       // inside using statement
       ds.doSomething();
  }

當 SomeDisposable 被初始化,即代碼塊被執行時, MemberThatThrowsAnException拋出異常時會發生什么?

如果我們在using塊的 scope之外調用這些成員構造函數,這有什么區別嗎?

  class TypeThatThrowsAnException 
  {
       public TypeThatThrowsAnException() 
       {
           throw new Exception();
       }
  }

  class SomeClass 
  {
       public static TypeThatThrowsAnException StaticMember 
       {
          get
          {
               return new TypeThatThrowsAnException();
          }
       }
  } 

  using (SomeDisposable ds = new SomeDisposable() {
       MemberThatThrowsAnException = SomeClass.StaticMember
  })
  {
       // inside using statement
       ds.doSomething();
  }

在某些情況下,這可能非常好且可讀,但我想知道這種方式是否有任何警告或陷阱 或者說一路走不通 除此之外,您還需要牢記可讀性。

Object 初始化程序在某種意義上是一個紅鯡魚......但它們是可以避免問題的一個例子。

在資源獲取表達式正常完成之前,object 不會被using語句“保護”。 換句話說,你的代碼是這樣的:

SomeDisposable tmp = new SomeDisposable();
tmp.MemberThatThrowsAnException = new TypeThatThrowsAnException();

using (SomeDisposable ds = tmp)
{
    // Stuff
}

這更明顯是有問題的:)

當然解決方案是using語句中分配屬性:

using (SomeDisposable ds = new SomeDisposable())
{
    MemberThatThrowsAnException = new TypeThatThrowsAnException();
    // Stuff
}

現在我們只依賴SomeDisposable的構造函數它最終拋出異常時自行清理——這是一個更合理的要求。

據我所知,您的 SomeDisposable class 具有類型為 TypeThatThrowsAnException 的屬性,您在實例化 SomeDisposable 時正在初始化該屬性 - 是嗎?

using () 即 Dispose 模式是一個簡寫,它實際上發出了這個:-

SomeDisposable ds = null;

try
{
    ds = new SomeDisposable();
}
finally
{
    if (ds != null)
        ds.Dispose();
}

因此,如果您的類型的構造函數拋出異常,控制將立即傳遞給 finally 塊。

在 Ayende 的博客上找到這篇文章 這是關於using語句中的 object 初始化程序,但它似乎與您的問題有關。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM