[英]using “using” too much?
鑒於以下代碼,我認為不再需要finally塊來關閉閱讀器或連接(如果它仍然可用)。 使用這么多嵌套的“使用”語句有什么好處或缺點嗎? 或者我應該走最后的街區路線?
List<string> platforms = new List<string>();
NpgsqlDataReader reader = null;
try
{
using (NpgsqlConnection conn = new NpgsqlConnection(GetConnectionString()))
{
// Making connection with Npgsql provider
string sql = @"SELECT platforms.""name"" FROM public.""platforms""";
using (NpgsqlCommand command = new NpgsqlCommand(sql))
{
command.Connection = conn;
command.CommandType = System.Data.CommandType.Text;
conn.Open();
using (reader = command.ExecuteReader())
{
while (reader.Read())
{
platforms.Add((string)reader["name"].ToString());
}
}
}
}
}
catch (Exception err)
{
HandleError(err, "GetPlatforms");
}
finally
{
platforms = null;
if (!reader.IsClosed)
{
reader.Close();
}
}
它確保在使用塊完成時釋放資源。 每個MSDN :
using語句允許程序員指定何時使用資源的對象應該釋放它們。 提供給using語句的對象必須實現IDisposable接口。 此接口提供Dispose方法,該方法應釋放對象的資源。
當達到using語句的結尾或者拋出異常並且控制在語句結束之前離開語句塊時,可以退出using語句。
我沒有看到您在代碼中列出的多個using
語句塊有任何問題。 它確保釋放資源,並確保程序員不會忘記。
如果您不喜歡這個標識,那么您可以重寫它,如下所示:
using (StreamWriter w1 = File.CreateText("W1"))
using (StreamWriter w2 = File.CreateText("W2"))
{
// code here
}
另請參閱關於C#中嵌套使用語句的此SO問題
你真的知道如何using
get編譯嗎?
服用
using (var disposableObject = new DisposableObject())
{
// do something with it
}
get編譯為(或多或少):
IDisposable disposableObject = new DisposableObject();
try
{
// do something with it
}
finally
{
if (disposableObject != null)
{
disposableObject.Dispose();
}
}
只是一個想法:在哪些情況下會發生異常?
猜測:我想NpgsqlConnection
在.Dispose()
本身上調用.Close()
- 但你必須用eg驗證。 .NET Reflector
正如你通過評論要求的那樣:
catch
...你明確知道什么可能出錯 - 把它分成幾個捕獲 using
語句:) ...除了pt。 1 如果您使用“使用”塊,則無需最終使用。
只是關閉讀取和連接。
碼
使用系統; 使用System.Collections.Generic; 使用System.Linq; 使用System.Text;
namespace BlogSamples
{
class Program
{
static void Main(string[] args)
{
using (Car myCar = new Car(1))
{
myCar.Run();
}
}
}
}
IL代碼
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 37 (0x25)
.maxstack 2
.locals init ([0] class BlogSamples.Car myCar,
[1] bool CS$4$0000)
IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: newobj instance void BlogSamples.Car::.ctor(int32)
IL_0007: stloc.0
.try
{
IL_0008: nop
IL_0009: ldloc.0
IL_000a: callvirt instance void BlogSamples.Car::Run()
IL_000f: nop
IL_0010: nop
IL_0011: leave.s IL_0023
} // end .try
finally
{
IL_0013: ldloc.0
IL_0014: ldnull
IL_0015: ceq
IL_0017: stloc.1
IL_0018: ldloc.1
IL_0019: brtrue.s IL_0022
IL_001b: ldloc.0
IL_001c: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0021: nop
IL_0022: endfinally
} // end handler
IL_0023: nop
IL_0024: ret
} // end of method Program::Main
正如你在這里看到的那樣,使用block是在try ... finally中轉換的。 但該類必須實現IDispose接口
我不知道除了代碼縮進之外的任何缺點。 顯而易見的是,您不必擔心丟棄物體,因為一旦使用支架留下它們就會被丟棄。
我注意到在你的錯誤處理程序中,你傳遞的是看起來像方法的名稱。 對於更通用的一個,您可以通過添加到工具箱中來使用,或者創建一個類似於以下內容的片段來自動獲取方法和類名。 您可以使用反射來獲取這些詳細信息。
ErrorHandler.Handler.HandleError(ex, System.Reflection.MethodBase.GetCurrentMethod().Name, System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName);
我認為你的代碼是相當不錯的,但我個人寧願重構一個using子句來分離函數,因為有5個連續的花括號(即})會使代碼不易讀取。 但這是我的觀點 - 我喜歡盡可能降低壓痕水平。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.