以下是有关此主题的两个先前问题:
我今天正在工作,认为如果将此功能添加到 C# 语言中,这可能是一个合适的语法。大家对此有什么意见吗?
e
的类型必须是列出的每个异常类型的基类型或接口。
编辑:在此示例中,catch 块处理
ArgumentNullException
或 ArgumentOutOfRangeException
,并将异常实例放置在名为 ArgumentException
的 e
类型变量中。除了列出的两种类型之外,它不处理任何其他类型的 ArgumentException
。我认为对于 ,
和 as
的关联性存在一些混淆。
编辑 2: 如果列出的异常全部向上转换为
e
类型的变量,则代码将干净地编译为 MSIL,无需任何转换或显式类型检查,使其比当前的语法更快(可能显着)如果它不是您想要的两个之一,则先捕获 ArgumentException
,然后再捕获 throw;
。如果您捕获 Exception
并检查两种可能的类型来处理并重新抛出(如果是其他类型),则问题会更加明显。
try
{
}
catch (ArgumentNullException, ArgumentOutOfRangeException as ArgumentException e)
{
}
看这个:
酷还是愚蠢?捕获(异常[NamingException,CreateException] e)
我对这个问题的回答是,他们应该让你像使用块一样“堆叠”它们:
try
{
}
catch (ArgumentNullException e)
catch (ArgumentOutOfRangeException e)
catch (ArgumentException e)
{
}
虽然我看到你会选择 and 而不是 or 。就我个人而言,我不认为 and 方法非常有用,因为您已经被限制为真正的非接口异常类型并且没有双重继承。
在 Java 7 中计划包含此功能,语法如下:
try {
return klass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new AssertionError(e);
}
编辑:我认为其目的是让 e 的静态类型成为列出的异常的最具体的公共超类。 (在 Java 中,只能抛出 java.lang.Throwable 类的实例,因此使用公共超级接口进行捕获的效用有限,因为无法重新抛出异常。)
您已经可以做到这一点,只需
try{}
catch(Exception e)
{}
因为所有异常都源自 System.Exception。您将像上面一样,确定 catch 块本身中的异常类型。
如果
ArgumentNullException
和ArgumentOutOfRangeException
有不同的接口,正确投射会很痛苦;
例如
ArgumentOutOfRangeException
有一个 ActualValue
属性;如果您必须使用它,您将以类似以下内容结束:
if(e is ArgumentOutOfRangeException)
{
// use e.ActualValue
}
else
{
// use e.Data
}
我发现自己在 C# 中并不经常需要这种情况,而在 Java 中,我发现在各种情况下我必须捕获一堆已检查的异常并将它们全部包装在我的方法声明抛出的不同异常中。
这就是我可能想要一些语法:
try
{
}
wrap (OneException as AnotherException)
catch (HandleableException e)
{
// Actual handling for some exception types
}
...但是,我再次发现自己在 Java 中做的事情比在 C# 中做的多。
还有其他增强功能,这些增强功能在我的 C# 列表中比这要高得多:)
你可以抓住
System.Exception
并检查类型。例如
try
{
//your code.
}
catch (Exception ex)
{
if(ex is ArgumentException || ex is FormatException)
{
//do something
}
else
{
throw;
}
}
只有在您不声明实例 (e) 的情况下,这才有效。如果你引用块内的 e,它是什么?