0

MySqlDataReader を初期化したり、値を割り当てたりせずに宣言したいと考えています。以下のコードのように。

MySqlDataReader rdr;

try
{ /* stuff to open the MySqlDataReader and use it, not important for my question */ }
catch (Exception e)
{ /* error handling stuff, not important for my question */ }
finally
{
    /* code to close the reader when things have gone wrong */
    try
    {
        if (rdr != null)
        {
            if (rdr.IsClosed == false)
            {
                rdr.Close();
            }
        }
    }
    catch (Exception e)
    { /* error handling stuff, not important for my question */ }
}

その理由は、実行時エラーが実際に発生した場合、try の finally セクションで MySqlDataReader を閉じたいからです。そのため、try の前に MySqlDataReader を宣言する必要があります。そうしないと、finally コードの範囲外になります。

ただし、上記のコードをコンパイルすると、コンパイル時エラー「割り当てられていないローカル変数 'rdr' の使用」が表示されるため、たとえば何かに設定したい

MySqlDataReader rdr = New MySqlDataReader();

しかし、これにより、「型 'MySql.Data.MySqlClient.MySqlDataReader' にはコンストラクターが定義されていません」というコンパイル時エラーが表示されます。コマンドオブジェクトの結果を割り当てると、コードがコンパイルされますが、それはうまくいかない可能性があり、私の試みがキャッチしようとしていることです。

MySqlDataReader オブジェクトが最初の繰り返しから閉じられていない場合、この関数が 2 回目に呼び出されると、2 回目にクラッシュします。

では、問題が発生したときに MySqlDataReader オブジェクトをクリーンアップするにはどうすればよいでしょうか?

4

2 に答える 2

2

Just assign it with null. The compiler will know a value has assigned, although it is null.

MySqlDataReader rdr = null;

In your finally block, check on the null value.

MySqlDataReader rdr = null;

try
{
    ... // do stuff here
}
finally
{
    if (rdr != null)
    {
        // cleanup
    }
}

Or use using if possible. It will cleanup rdr for you:

using (MySqlDataReader rdr = ... )
{
}
于 2014-06-23T10:35:03.547 に答える
1

One option is to initialize it to null to start with:

MySqlDataReader rdr = null;

After all, you're already checking whether it's null within the finally block in your sample code, so that's fine.

It's not clear why you're not just using a using statement though. You can always put a try/catch inside (or outside) that.

于 2014-06-23T10:34:54.780 に答える