1

由于输出存储过程参数的解析明显放错了位置,我遇到了这个错误。

在控制离开当前方法之前,必须分配 out 参数“whichID”

代码:

public static bool CreateFilmTest(string param1, string param2, out int whichID)
{
            DbCommand com = GenericDataAccess.CreateCommand();
            com.CommandText = "CatalogCreateFilmTest";

            DbParameter param = com.CreateParameter();
            param.ParameterName = "@param1";
            param.Value = param1;
            param.DbType = DbType.String;
            param.Size = 200;
            com.Parameters.Add(param);
            ..........            
            param = com.CreateParameter();
            param.ParameterName = "@Fid";
            param.Direction = ParameterDirection.Output;
            param.DbType = DbType.Int32;
            com.Parameters.Add(param);

            int result = -1;

            try
            {
                result = GenericDataAccess.ExecuteNonQuery(com);

                whichID = Int32.Parse(com.Parameters["@Fid"].Value.ToString());

            }
            catch
            {
                // ....
            }


           return (result >= 1);
}

如果我将: whichID = Int32.Parse(com.Parameters["@Fid"].Value.ToString()); line放在 return line 之前,该方法将成功执行并给出正确的结果。

但是,如果我将它放在 try 括号内,它会给出开头提到的错误。

为什么这样?

我的第一选择是把它放在 try 括号内,因为如果由于任何原因ExecuteNonQuery失败,处理它的输出参数 () 是没有意义的whichID。因此,我认为最好将 try 块中的两个元素(过程的执行和过程中的输出参数的处理)结合起来,以在发生错误的情况下触发内部对这种情况的优雅处理catch

非常感谢您的意见。谢谢。安娜

4

3 回答 3

1

原因是,如果您将其放在 try 中,则不会发生合理确定的分配。您可以通过在方法的前面为其分配一个默认值来解决此问题(例如,在第一行将其设置为零)。

于 2012-06-12T11:58:47.903 回答
1

如果没有记忆,这是因为它try的编译方式包含一个 inner try,这意味着程序流程可能不会try在继续之前正确地进入 (即使您通常假设它try本身不会中断程序流程与,说,if确实)。

然后,这将触发编译器检查out在退出方法之前分配的参数。

只需默认方法顶部的值即可。


记忆确实有用……语言规范无所不知。

12.3.3.15 Try-catch-finally 语句(特别是对 的赋值分析try-catch-finally)。

形式为 try-catch-finally 语句的确定赋值分析:

try [try-block]
catch ( … ) [catch-block-1]
…
catch ( … ) [catch-block-n]
finally [finally-block]

就像语句是包含 try-catch 语句的 try-finally 语句一样完成:

try {
try [try-block]
catch ( … ) [catch-block-1]
…
catch ( … ) [catch-block-n]
}
finally [finally-block]

一个例子:

class A
{
    static void F() {
        int i, j;
        try {
            goto LABEL;
            // neither i nor j definitely assigned
            i = 1;
            // i definitely assigned
        }
        catch {
            // neither i nor j definitely assigned
            i = 3;
            // i definitely assigned
        }
        finally {
            // neither i nor j definitely assigned
            j = 5;
            // j definitely assigned
        }
        // i and j definitely assigned
        LABEL:;
        // j definitely assigned
    }
}
于 2012-06-12T11:59:12.380 回答
0

您收到该错误的原因是由于编译器处理 try/catch 的方式。try/catch 块在某种意义上是一个条件语句。其中的代码只有在它之前的代码没有抛出异常的情况下才会执行,而代码本身只有在它自己没有抛出异常的情况下才会完成执行。

如果您仅在 try 中(或仅在 catch(es) 中)定义变量,那么您无法确定这些代码行是否会运行。如果您的变量仅在 try 块中定义,那么如果之前有异常,或者在定义的行上,它可能会被跳过。如果您的变量仅在 catch 子句中定义,那么如果没有发生异常,它将被跳过。

你最好在进入 try-catch 块之前声明一个默认值,或者在你的 catch 子句中声明一个失败值。

于 2012-06-12T12:25:44.033 回答