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 语句只会捕获最后一个。知道为什么它只捕捉其中一个词吗?我希望它能够捕获所有这些并将它们全部添加到 StringBuilder badData。

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 - 这意味着它的旧实例(以及其中包含的任何值)都将被丢弃。如果您在 catch 块中删除此行:

badData = new StringBuilder();

你可能会更接近你想去的地方。

当您在执行此操作后最终遇到空指针异常时,您需要确保将badData其实例化到= new StringBuilder();(如您所拥有的那样)任何您已经声明它的地方 - IE,作为方法外部的实例变量。

于 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 类型的末尾添加另一个捕获,以找出早期爆炸的原因。(正如齐泽默所说,停止重新初始化某人。)

于 2012-09-09T12:44:34.410 回答