1

以下に示す私のtry/catchでは、アプリケーションはユーザーがテキストボックスに入力した単語をループします。(この部分が機能することはすでに確認済みです。)単語をループするときに、各単語に以下の関数を渡します。

private string runQuery(string data)
    {
        // Step 1 - Declare the query and parameters
        SqlCeConnection connection = new SqlCeConnection(@"Data Source=keywordDB.sdf");
        SqlCeCommand cmd = new SqlCeCommand("SELECT abbrev, description FROM abbreviations WHERE abbrev LIKE @abbrev", connection);
        cmd.Parameters.AddWithValue("@abbrev", data);
        SqlCeDataReader reader;

        try
        {
            // Step 2 - Opens the connection
            connection.Open();

            // Step 3- Execute query and assign the data to abbrevQueryResult and results
            reader = cmd.ExecuteReader();
            reader.Read();
            abbrevQueryResult = reader[0].ToString();
            results = reader[1].ToString();

            // Step 4 compare abbrevQueryResult to data entered by user in textbox
            if (abbrevQueryResult.ToLower().Equals(data.ToLowerInvariant()))
            {
                returnResults.Append(" " + results + ",");
            }
        }

        catch (InvalidOperationException e)
        {
            badData = new StringBuilder();
            badData.Append(" " + data);
        }

        finally
        {
            if (connection != null)
            {
                connection.Close();
            }
        }

        return returnResults.ToString();
    }

6つの単語を入力すると、そのうち3つは正常に機能し、3つはcatchステートメントによってキャッチされ、catchステートメントは最後の1つだけをキャッチすることに気付きました。なぜそれが単語の1つだけを捕らえるのか考えますか?それらすべてをキャッチして、StringBuilderbadDataに追加したいと思います。

4

5 に答える 5

5

このような通常の状況でデータの有効性を判断するために、try/catchおよび例外メカニズムを使用するべきではありません。これが、プログラムをクラッシュさせる可能性のある例外的なケースを処理することを目的としているため、「例外」と呼ばれる理由です。入力の特定の割合が無効になると予想される場合は、通常の論理テストを実行してください。

 if (valid(word) {function(word);} else {addToErrorList(word);} 
于 2012-09-09T12:14:50.187 に答える
3

badData宣言されている場所は表示されません。ただし、catchブロックが呼び出されるたびbadDataに、新しいStringBuilderにリセットされます。つまり、古いインスタンス(およびその中に保持されている値)は破棄されます。キャッチブロック内でこの行を削除した場合:

badData = new StringBuilder();

あなたはおそらくあなたがなりたい場所に近づくでしょう。

これを行った後にnullポインター例外が発生した場合は、メソッドの外部のインスタンス変数として、既に宣言されている場所(IE)にbadDataインスタンス化されていることを確認する必要があります。= new StringBuilder();

于 2012-09-09T12:12:51.133 に答える
1

badData = new StringBuilder();毎回catchブロックで設定しています。だから、それは3回捕らえられますが、あなたはあなたの最後の悪い言葉しか見ませんStringBuilder

于 2012-09-09T12:15:37.130 に答える
1

すべてのエラーを封じ込めたい場合badDataは、catch句で変数を初期化することはできません。これは、キャッチされた例外ごとに変数をリセットするためです。他の場所で初期化すると、これで機能します。

クラスのトップで初期化する:

public class MyClass {
     private StringBuilder badData = new StringBuilder();

     // Other code
}

コンストラクターで初期化:

public class MyClass {
     private StringBuilder badData;

     public MyClass() {
          badData = new StringBuilder();
     }
}

このようにすることで、オブジェクトが存在する限り変数が存在し、catch句の初期化を削除するだけでStringBuilder、例外がキャッチされるたびに変数が新しいオブジェクトにリセットされないようになります(これにより、最後のエラーだけでなく、すべてのエラーが追加されます)。

于 2012-09-09T12:18:13.480 に答える
1

そのSQLアクセスコードは非常に壊れやすく、それが原因だと思いますが、要点は、InvalidOperationExceptionをキャッチするだけなので、例外処理が適切ではないということです。タイプExceptionの最後に別のキャッチを追加して、初期の爆撃の原因を見つけます。(そして、ziesemerが言ったように、sbの再初期化を停止します。)

于 2012-09-09T12:44:34.410 に答える