7

私は本当にこれを頭から取り除きたいです。以下のコードを参照してください。

using (DataTable resultTable = DBUtility.GetSingleDBTableResult(connectionString, "SELECT * FROM MyDBTable")) {
    List<string> resultsList = new List<string>();
    foreach (DataRow dataRow in resultTable.Rows) {
        resultsList.Add(dataRow[0].ToString());
    }
    return resultsList;
}

データテーブルは破棄されますか?誰かがこれがtry/catch / finallyブロックにどのように変換されるかを説明できますか?MSDNは、例外が発生した場合でもDisposeメソッドが呼び出されると述べていますが、returnステートメントはどうでしょうか。

または、以下のコードを使用する必要があります:

List<string> resultsList = new List<string>();
using (DataTable resultTable = DBUtility.GetSingleDBTableResult(connectionString, "SELECT * FROM MyDBTable")) {
    foreach (DataRow dataRow in resultTable.Rows) {
        resultsList.Add(dataRow[0].ToString());
    }
}
return resultsList;

おそらく、2番目のものを使用する必要がありますが、私はただ啓蒙が必要です:)。説明してください。ありがとう。

4

4 に答える 4

5

usingステートメントは単なる構文糖衣であり、try/finallyブロックに変換されます。コードから始めて、C#コンパイラがusingブロックをtry/finallyブロックに変換する方法を次に示します。

        try
        {
            DataTable resultTable = DBUtility.GetSingleDBTableResult(connectionString, "SELECT * FROM MyDBTable");
            List<string> resultsList = new List<string>();
            foreach (DataRow dataRow in resultTable.Rows)
            {
                resultsList.Add(dataRow[0].ToString());
            }
            return resultsList; 
        }
        finally
        {
            resultTable.Dispose();
        }

コードからわかるように、resultTableは、returnステートメントに関係なく確実に破棄されます。usingブロックは、オブジェクトがスコープの後に破棄されることを確認するだけです。

最初のコードは私には問題ないように見え、変更する必要はありません。

于 2010-07-06T04:22:36.453 に答える
4

Using 例外をキャッチせず.Dispose()、呼び出しを保証するだけです。

それの訳は、

using (ResourceType resource = new ResourceType())と同等です:

ResourceType resource;
try 
{
     resource = new ResourceType();
     /* The insides of the using block */
}
finally
{
    resource.Dispose();
}

.Dispose()呼び出しは常に評価されます。Disposeブロック内に戻った場合でもusing(「実際に」戻る前に)、呼び出しは評価されます。Dispose例外がスローされた場合でも、呼び出しは評価されます。

ただし、例外がスローされた場合でも、その例外により、後続のコード行が評価されなくなります(常に.Dispose()評価される例外を除く)。

そのため、例外が発生した場合、あなたreturnはどちらのステートメントにも戻りませんが、DataTableそれでもあなたは処分されます。

エラーが発生した場合でも、返品が発生することを保証したい場合は、次のようにします。

List resultsList = new List();
try
{
    using (DataTable resultTable = DBUtility.GetSingleDBTableResult(connectionString, "SELECT * FROM MyDBTable")) 
    {
        foreach (DataRow dataRow in resultTable.Rows) 
        {
            resultsList.Add(dataRow[0].ToString());
        }
    }
}
catch
{
}
return resultsList;
于 2010-07-06T04:20:11.400 に答える
1

どちらの場合も、 DataTableは破棄されます(.Dispose呼び出されます)。

に変換され、try/finallyDispose呼び出されますfinally。最後に、名前が示すように、を呼び出しても呼び出されますreturn

于 2010-07-06T04:18:58.723 に答える
1

両方の例で、Disposeが呼び出されます。これは、usingステートメントがtry/finallyブロックに展開されるためです。

C#言語仕様(8.13 usingステートメント)を読んで、さまざまなシナリオ(参照型、null許容でない値型、および動的型)を見つけてください。

は参照型であるためDataTable、最初のサンプルは次のように展開されます。

{
    DataTable resultTable = DBUtility.GetSingleDBTableResult(connectionString, "SELECT * FROM MyDBTable");
    try {
        List<string> resultsList = new List<string>();
        foreach (DataRow dataRow in resultTable.Rows) {
           resultsList.Add(dataRow[0].ToString());
        }
        return resultsList;
    }
    finally {
        if (resultTable != null) ((IDisposable)resultTable).Dispose();
    }
}
于 2010-07-06T04:39:13.523 に答える