17

次のコードがあるとします。

private void UpdateDB(QuoteDataSet dataSet, Strint tableName)
{
    using(SQLiteConnection conn = new SQLiteConnection(_connectionString))
    {
        conn.Open();
        using (SQLiteTransaction transaction = conn.BeginTransaction())
        {
            using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM " + tableName, conn))
            {
                using (SQLiteDataAdapter sqliteAdapter = new SQLiteDataAdapter())
                {
                    sqliteAdapter.Update(dataSet, tableName);
                }
            }
            transaction.Commit();
        }
    }
}

C#のドキュメントには、usingステートメントを使用するとスコープ内のオブジェクトが破棄されると記載されており、try/finally句を使用する必要がないことが示唆されている場所をいくつか見ました。

私は通常、接続をtry / finallyで囲み、finally節で常に接続を閉じます。上記のコードを考えると、例外が発生した場合に接続が閉じられると想定するのは合理的ですか?

4

5 に答える 5

19

あなたは正しいです; usingステートメントは/ブロックにコンパイルさtryfinallyます

コンパイラusing(resource) statement;は次のコードに変換されます。

{
   ResourceType resource = expression;
   try {
      statement;
   }
   finally {
      if (resource != null) ((IDisposable)resource).Dispose();
   }
}

(キャスト先は、明示的に実装IDisposableする場合です。ResourceTypeIDisposable

于 2010-04-25T21:31:13.287 に答える
10

はい、try/finallyまたはusingステートメントを使用する必要があります。両方は必要ありません。

usingステートメントはtry/ finalとほぼ同じですが、C#3ではusingブロック内の変数に再割り当てできない点が異なります。

using (IDisposable d = foo())
{
     d = null; // Error:  Cannot assign to 'd' because it is a 'using variable'
}

以前は再割り当てできましたが、新しく割り当てられたオブジェクトではなく、元のオブジェクトが引き続き破棄され、次のコンパイル警告も表示されます。

usingまたはlockステートメントの引数であるローカル'd'への割り当てが正しくない可能性があります。Dispose呼び出しまたはロック解除は、ローカルの元の値で行われます。

于 2010-04-25T21:27:42.427 に答える
6

はい、ステートメントはほとんどブロックusingの省略形です。try ... finally

たとえば、このコードは...

using (MyDisposableType foo = new MyDisposableType())
{
    foo.DoSomething();
}

...次のようになります...

{
    MyDisposableType foo = new MyDisposableType();
    try
    {
        foo.DoSomething();
    }
    finally
    {
        if (foo != null)
            ((IDisposable)foo).Dispose();
    }
}
于 2010-04-25T21:28:33.823 に答える
1

Using()は、関連するコードブロック内で発生したかどうかに関係なく、パラメーター内でインスタンス化されたアイテムが確実に破棄されるようにします。SQLiteConnectionこれには、データベース接続が正しく処理されると想定してデータベース接続を閉じることも含まれます。

于 2010-04-25T21:30:51.940 に答える
1

例外が発生した場合、接続は閉じられると想定できます。

于 2010-04-25T21:27:41.347 に答える