我听过并读过,我们需要在Code time
中了解我们将要遇到的例外情况并提供必要的捕获量。
现在我们无法推断刚从Exception
类发生的实际异常的类型,然后将其转换并获取所需的信息?
例如,考虑一下:
private void button1_Click(object sender, EventArgs e)
{
try
{
//try doing something to generate and exception
int blah =8 / Convert.ToInt32(txtBox.Text);
}
catch (Exception ex)
{
//ex.GetType().Name
//getting the type and casting it according to the retrieved name
//and finally showing the more detailed info of the occurred exception
//for example like this?
//MessageBox((ex.GetType())ex).Message);
}
}
这只是传达我意义的一个示例,假设如果可能的话,我们会创建一个继承自Exception
的自定义类,并为此目的进行所需的工作。
我们不能这样做吗?如果我们能怎样才能施展它?如果不能这样做,为什么呢?
答案 0 :(得分:2)
如果需要,您可以将异常处理逻辑委托给某些定义良好的模块,其目的是...处理异常:)也许这样.. ?
try {
// code that throws something
} catch (Exception e) {
myExceptionHandlingStrategy.handleException(e);
}
其中 myExceptionHandlingStrategy 是 MyExceptionHandlingStrategy 的一个实例,该模块公开接口 IExceptionHandlingStrategy ,定义(可能)如下:
interface IExceptionHandlingStrategy {
void handleException(Exception e);
}
然后,在该界面的某些实现中(您可能有很多),您可以自由地执行以下操作:
if (e is SomethingBadException) {
// show some message
} else if (e is SomeOtherKindOfException) {
// do something else instead
} else {
throw new CannotHandleThisException(e);
}
PS:否反射:)
答案 1 :(得分:2)
举一个Chris Cudmore建议的例子
try
{
}
catch (System.FormatException FormatEx)
{
//logic here
}
catch (Exception ex)
{
//generic catch-all
MessageBox(ex.Message);
throw;
}
大多数情况下,您希望事先知道异常的类型,以便您可以专门处理该异常(对于任何清理/恢复任务),而不是因为您可以访问基本成员,例如Exception.Message
。 / p>
答案 2 :(得分:2)
您问题的简短回答是:是的,当然(有点)。一个更有意义的答案将经历试图解释如何进行适当的异常处理的所有痛苦。网上有大量关于这个主题的文章,还有一些实用的有价值(和昂贵)的书籍。 SO中的一个问题可以让你朝着正确的方向前进,但仅此而已。
您的示例代码非常简单,就像示例的标准一样。丑陋的事实是,你几乎从未在日常软件开发中遇到如此简单的问题。因此,很难制作一个故事,并说明一个简单而具体的案例有点复杂的想法。已经有很多尝试来解决你在问题中提到的问题,例如Exception Handling Application Block。
但是,在处理异常以注意其存在以使用户/开发人员确切知道应用程序中的错误,以及另一方面处理异常以对程序进行某种非正统控制之间存在本质区别。执行流程。
在几乎所有情况下吞咽异常都是不可接受的。该规则的例外情况(双关语意图)数量有限。只有当您可以从错误中恢复而不会对程序的完整流程产生负面影响时,您才应该捕获异常,这不仅仅是因为您想要“处理”它们。这基本上就是我不同意@ martin-lariviere和@andrei给出的解决方案的原因。
当你捕获异常并且不能很好地处理它时,你可能会无意中影响被调用方法的后置条件,这可能会间接地影响调用代码的执行,因为对被调用的逻辑块做出了未满足的假设。反过来,所有这些都可能导致程序的不稳定状态。简而言之:一个潜伏的恶魔潜伏在随时准备咬你,渴望破坏一些数据(至少)。
示例方法是void
,但是如果它是其他什么呢?如果在确定某些返回值所需的操作中间发生异常怎么办?你会如何处理这种例外?你基本上有两个选择:
( Dangerous )吞下异常,使用一些默认值进行计算,并返回可能会使调用代码(和用户)“惊讶”的可能不准确的结果。即使在这种情况下,至少记录错误也是明智之举。如果他必须追踪由这种特殊不端行为引起的错误,那么你的“未来你”有一天可能会感激不尽。它可能是安全的,但这取决于所实施的特定方法(特别是其后置条件和不变量)。
( Delicate )允许异常传播到调用代码; “按原样”或包含在其他一些例外中。在这种情况下,您可能会记录错误,但这不是必需的。不过,您可能会采取措施确保某些资源得到正确释放,并且可能会有一些半初始化对象或中间修改后的数据再次恢复到某个稳定状态。
任一选项都要求采取合理的判断调用来实现适当的异常处理策略,并且应该考虑每个可能引发异常的操作!显然,每次开发人员在键入任何代码时都应该考虑到这一点。这是残酷的。
因此,您的问题没有简单的正确的答案。也许你想要一个模式来解决第二个选项( Delicate )中的所有事情。可悲的是,没有。也许在第二篇文章中我可以详细说明:UI中的错误条件,异常和通知/警报。这是一个艰难的主题,这个“答案”已经非常冗长。
答案 3 :(得分:1)
我认为没有必要,但这是一个例子:
try
{
int[] numbers = new int[2];
numbers[6] = 345;
}
catch (Exception ex)
{
Type t = ex.GetType();
var props = t.GetProperties();
foreach (var p in props)
{
Console.WriteLine(p.Name + " : " + p.GetValue(ex));
}
}
答案 4 :(得分:0)
不确定您的意图。
您的ex
变量应该包含生成的错误消息以及内部列表。
如果您想拥有该类型的名称你可以做到以下几点:
catch (System.Exception _ex)
{
switch (_ex.GetType().FullName)
{
case "System.FormatException":
*//Do what you want in case of a FormatException error...*
break;
case "System.*other type*":
*//Do what you want in case of a ...*
break;
default:
break;
}
}