[英]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.