在C#中处理异常的最佳实践是什么?

在C#中处理异常的最佳实践是什么?,c#,try-catch,C#,Try Catch,我的网页中有以下代码: btnTest_Click(object sender, EventArgs e) { ... bool ret=myFunc(...); if (ret) {...} else { lblStatus.Text="Some Text"; lblStatus.Visible=true; } } private bool myFunc(...) { bool ret=false

我的网页中有以下代码:

btnTest_Click(object sender, EventArgs e)
{
    ...
    bool ret=myFunc(...);
    if (ret)
    {...}
    else
    {
        lblStatus.Text="Some Text";
        lblStatus.Visible=true;
    }
}

private bool myFunc(...)
{
    bool ret=false;
    try
    {
        ...
        ret=true;
    }
    catch (Exception ex)
    {
        lblStatus.Text="Other Text";
        lblStatus.Visible=true;
    }
    return ret;
}
如果myFunc中发生异常,则lblStatus始终显示“某些文本”而不是“其他文本”。这意味着myFunc中的catch块实际上没有任何意义。我想知道如何修复此代码以更好地处理异常

更新:也许我的例子不是很好。但我的主要目的是询问调用和被调用函数之间异常处理的最佳实践。

它显示“一些文本”,因为当在
myFunc
中发生异常时,它返回false。然后进入
btnTest\u Click
方法的
else
块,在该块中再次将
lblStatus.Text
设置为“某些文本”

因此,基本上,您将标签的文本设置为“其他文本”,然后设置为“某些文本”。

它显示“某些文本”,因为在
myFunc
中发生异常时,它返回false。然后进入
btnTest\u Click
方法的
else
块,在该块中再次将
lblStatus.Text
设置为“某些文本”


因此,基本上,您将标签文本设置为“其他文本”,然后设置为“某些文本”。

为什么被调用函数将标签文本设置为异常,而调用方将其设置为成功

这是一个复杂的比喻。让一方负责UI(关注点分离),另一方负责工作。如果希望调用的函数具有容错性,请尝试以下操作:

private bool myFunc(...)
{
  bool ret ;
  try
  {
    ...
    ret=true;
  }
  catch
  {
    ret = false ;
  }
  return ret;
}
然后,您的来电者可以执行以下操作:

bool success = myFunc(...) ;
lblStatus.Text = success ? "Some Text" : "Other Text" ;
lblStatus.Visible = success ;

if ( success )
{
  // do something useful
}

为什么被调用函数将标签文本设置为异常,而调用方将其设置为成功

这是一个复杂的比喻。让一方负责UI(关注点分离),另一方负责工作。如果希望调用的函数具有容错性,请尝试以下操作:

private bool myFunc(...)
{
  bool ret ;
  try
  {
    ...
    ret=true;
  }
  catch
  {
    ret = false ;
  }
  return ret;
}
然后,您的来电者可以执行以下操作:

bool success = myFunc(...) ;
lblStatus.Text = success ? "Some Text" : "Other Text" ;
lblStatus.Visible = success ;

if ( success )
{
  // do something useful
}

异常处理很好。代码的问题是,如果返回值为
false
,则在标签中放入
“Some Text”
字符串,而这正是出现异常时的情况,因此它将替换
catch
块中的消息

切换案例:

if (ret) {
  // it went well, so set the text
  lblStatus.Text="Some Text";
  lblStatus.Visible=true;
} else {
  // an exception occured, so keep the text set by the catch block
}

异常处理很好。代码的问题是,如果返回值为
false
,则在标签中放入
“Some Text”
字符串,而这正是出现异常时的情况,因此它将替换
catch
块中的消息

切换案例:

if (ret) {
  // it went well, so set the text
  lblStatus.Text="Some Text";
  lblStatus.Visible=true;
} else {
  // an exception occured, so keep the text set by the catch block
}

这是一个复杂的问题,因此我将尝试将其分解

  • 就职能而言,我将努力坚持单一责任原则。它应该做一件定义明确的事情
  • 例外情况应该是,例外情况。因此,最好不要引发异常,但显然要在适当的时候处理它们。例如,最好在尝试使用某个变量之前将其测试为
    null
    (这会引发异常)。异常可能很慢(特别是当抛出大量异常时)
  • 我想说,你在哪里处理例外的问题取决于例外是谁的责任。如果
    myFunc
    要访问远程服务器并返回true或false状态,您希望它处理自己的IO异常。它可能不会处理(或重新调用)任何参数问题。这与第1点有关。负责处理连接过程的是功能,而不是提供正确的参数。如果其他人(或健忘的你)以后试图使用代码,隐藏某些异常可能会导致问题。例如,在此建立连接的
    myFunc
    中,如果隐藏参数异常,您可能不会意识到传递了错误的参数

  • 这是一个复杂的问题,因此我将尝试将其分解

  • 就职能而言,我将努力坚持单一责任原则。它应该做一件定义明确的事情
  • 例外情况应该是,例外情况。因此,最好不要引发异常,但显然要在适当的时候处理它们。例如,最好在尝试使用某个变量之前将其测试为
    null
    (这会引发异常)。异常可能很慢(特别是当抛出大量异常时)
  • 我想说,你在哪里处理例外的问题取决于例外是谁的责任。如果
    myFunc
    要访问远程服务器并返回true或false状态,您希望它处理自己的IO异常。它可能不会处理(或重新调用)任何参数问题。这与第1点有关。负责处理连接过程的是功能,而不是提供正确的参数。如果其他人(或健忘的你)以后试图使用代码,隐藏某些异常可能会导致问题。例如,在此建立连接的
    myFunc
    中,如果隐藏参数异常,您可能不会意识到传递了错误的参数

  • 如果您希望被告知在某个函数中遇到特定类型的错误,我建议您继承Exception并创建自己的Exception类。我会在btnTest_Click()处理程序中放置一个try-catch块,然后我会寻找捕获自定义异常类的方法。这样,您就不会失去检测myFunc()函数中发生的任何错误的机会。

    如果您想知道在某个函数中遇到了特定类型的错误,我建议您继承Exception并创建自己的Exception类。我会在btnTest_Click()处理程序中放置一个try-catch块,然后我会寻找捕获自定义异常类的方法。这样,您就不会失去检测myFunc()函数中发生的任何错误的机会。

    your
    catch
    c