編輯:兩個選項如下所示。安全返回構建的IDisposables的最佳方式是什麼?
如果你只是使用 IDisposable提供的功能,恰當地命名爲using
子句工作正常。如果你是將和IDisposable
包含在一個對象中,則包含對象本身需要爲IDisposable
,並且需要實現適當的模式(密封的IDisposable
類或者messier,但是standard virtual
pattern)。
但是有時候輔助工廠的方法對清潔很有好處。如果您在施工後直接返回IDisposable
,則表示您沒有問題,但如果您先構建它,然後修改或執行可能會在返回之前拋出異常的代碼,則需要安全地撥打.Dispose()
- 但只有,如果有的話一個錯誤。
例如,不安全的代碼看起來是這樣的......
DbCommand CreateCommandUnsafely(string commandText)
{
var newCommand = connection.CreateCommand();
newCommand.CommandText = commandText; //what if this throws?
return newCommand;
}
解決方案兩個安全變種如下...
DbCommand CreateCommandSafelyA(string commandText)
{
DbCommand newCommand = null;
bool success = false;
try {
newCommand = connection.CreateCommand();
newCommand.CommandText = commandText; //if this throws...
success=true;
return newCommand;
} finally{
if (!success && newCommand != null)
newCommand.Dispose(); //...we'll clean up here.
}
}
DbCommand CreateCommandSafelyB(string commandText)
{
DbCommand newCommand = null;
try {
newCommand = connection.CreateCommand();
newCommand.CommandText = commandText; //if this throws...
return newCommand;
} catch {
if (newCommand != null)
newCommand.Dispose(); //...we'll clean up here.
throw;
}
}
安全的變體,A是僅有一個線長,但似乎是慣用的方法。似乎沒有任何真正簡潔的解決方案,儘管下面的一些海報給出了一些使用lambda的選項來提取封裝的邏輯。
與上述任何安全方法的代碼膨脹仍然存在,並且與原先看起來像代碼特別嚴重......
return new MyDisposableThing {
OptionA = "X",
OptionB = B.Blabla,
Values = src.Values.Where(priority => priority > 1.0),
};
上面的代碼被安全地寫入是相當長的時間和更少的可讀因爲你不能再安全地使用縮短的setter語法。
這看起來像我在別處看到的代碼。你知道爲什麼這是可取的嗎? –
捕捉任意異常(正如其他答案似乎倡導的那樣)會在特殊情況下引發各種問題,應儘可能避免。通過將處置置於'finally'語句中,標準模式避免捕捉異常,並且(當對象創建失敗時)它模仿標稱'using'語句的行爲。 –