![](/img/trans.png)
[英]What are industry standard best practices for implementing custom exceptions in C#?
[英]What are best practices for handling exceptions in C#?
我的网页中有以下代码:
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块实际上没有任何意义。 我想知道如何修复此代码以更好地处理异常?
更新:也许我的榜样不是很好。 但是我的主要目的是询问最佳实践,以了解调用和被调用函数之间的异常处理。
为什么您的被调用函数将标签文本设置为异常,而调用方将其设置为成功?
那是一个混杂的隐喻。 让一方负责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
}
它显示“ Some Text”,因为当myFunc
发生异常时,它返回false。 然后进入btnTest_Click
方法的else
块,在此处将lblStatus.Text
再次设置为“ Some Text”。
因此,基本上,您将标签的文本设置为“其他文本”,然后设置为“某些文本”。
您的catch
子句正在做很多事情。 它捕获每个异常并“忘记”异常,将其抑制到调用堆栈的其余部分。 可以很好地解决问题,但我将尝试说明您的选择:
您通常有3个选择:
我全部使用。
选项1
您可以只实现您的功能,如果发生异常,则意味着发生了一些错误,并且您只是希望您的应用程序失败(至少到一定程度)
选项2
发生某些异常,您需要执行两个(或什至两个)之一
选项3该异常是预料之中的,您知道如何完全对其进行反应。 例如,在您的情况下,我倾向于认为您不在乎异常的类型,而是希望通过对给定的文本设置一些控件来实现“良好的默认设置”。
结论
没有银弹。 为每种情况使用最佳选项。 然而,捕获和“抑制” catch(Exception ex)
很少见,如果经常看到,通常意味着不好的编程。
异常处理就可以了。 代码的问题是,如果返回值为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
中,如果您隐藏参数异常,则可能不会意识到自己传递了错误的参数 如果要通知您在其中一个函数中遇到特定类型的错误,建议您继承Exception并创建自己的异常类。 我会在btnTest_Click()处理程序中放入try-catch块,然后查找您的自定义异常类。 这样,您将不会失去检测myFunc()函数内部发生的任何错误的机会。
我通常会设置一个错误处理系统。 这是一个简单的方法,但是可以将其包装为一个基类。 如果需要的话,我可以告诉你。
List<string> _errors;
void init()
{
_errors = new List<string>();
}
protected void Page_Load(object sender, EventArgs e)
{
init();
}
btnTest_Click(object sender, EventArgs e)
{
...
var result = myFunc(...);
if (result)
{...}
else
{
if (_errors.Count > 0)
{
var sb = new StringBuilder("<ul>");
foreach (string err in _errors)
{
sb.AppendLine(string.Format("<li>{0}</li>", err));
}
sb.AppendLine("</ul>");
lblStatus.Text=sb.ToString();//Make this a Literal
}
}
}
private bool myFunc(...)
{
var result = true;
try
{
...
...
}
catch (Exception ex)
{
result = false;
_errors.Add(ex.Message);
}
return result;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.