3

我知道为什么我不应该像这样使用开放的 catch 块:

int x = 0;
try
{
    x = GetXFromSomeplaceThatCanFail();
}
catch //Possibly (Exception) or (Exception e)
{
    //Ignore The Failure Because We Don't Care If It Fails
}
if (x != 0) //Yes I know I can use finally blocks to do something similar, but this is just an example case
{
    //Do Things With x
}

我完全意识到这会“吞下”诸如 OutOfMemoryException 之类的东西,这是一种不好的做法,可能会导致未检测到的故障/微妙的错误,这些都是可怕的事情

这就是为什么我要检查我的代码并确保没有这样的事情。通常,您会查看您在 try 块中使用的任何内容的文档并捕获预期的异常,或者知道某些操作会生成某些异常(例如访问具有索引的数组时的 IndexOutOfRangeException 等)。

但是,没有文档可以检查奇怪的情况以查看可能引发的异常(或者很难找到)。我自己的项目中的一个特定案例(变量名称通用且代码简化)仅在字符串字段存在时才使用动态类型来获取字符串字段,否则会通过提供“N/A”作为结果优雅地失败。再次提醒您,我知道这是错误的代码:

string theString = "Some Old Value From Previous Run/etc.";
try
{
    theString = (placeWhereValuesComeFrom as dynamic).TheString;
}
catch
{
    theString = "N/A";
}

在这种情况下,placeWhereValuesComeFrom 继承自 BaseClass,后者不(也不应该)提供 TheString。

我意识到我可以创建一个提供 TheString 并从 BaseClass 继承的中间类,然后从中继承。但是,动态解决方案的实施速度非常快,并且运行良好。除非针对我的特定场景提出更好的解决方案,否则我计划添加一个中间类并仅使相关类继承自它,然后像这样进行测试:

theString = placeWhereValuesComeFrom is Subclass ? ((Subclass)placeWhereValuesComeFrom).TheString : "N/A";

但是,假设我不想以任何理由重构以使用中间类,我应该在这里做什么?我怎样才能发现我应该在 catch 块中安全地忽略哪些可能的异常?如果没有真正的方法来“查找”可以抛出哪些异常,那么其他类似情况呢?

4

1 回答 1

2

您应该在这里处理的唯一异常是运行时绑定失败;当动态对象没有实现时TheString。抛出的异常类型是Microsoft.System.CSharp.RuntimeBinder.RuntimeBinderException.

因此,您的代码应如下所示:

try
{
    str = myDynamicObject.TheString;
}
catch (Microsoft.System.CSharp.RuntimeBinder.RuntimeBinderException)
{
    //Binding failure
    str = "N/A"
}
catch ( ... //exceptions you know TheString can throw, if any...)
{
    //Handle
}
// any other exception you don't know how To handle...don't handle it
于 2016-08-15T15:55:07.070 回答