2009-10-07 46 views
1

以下是关于这个话题前两个问题:C#中多类型catch块的可能语法?

我今天的工作,并认为这可能是一个合适的语法应该这个功能曾经被添加到C#语言。任何人对此有任何意见?

e的类型必须是列出的每种异常类型的基本类型或接口。

编辑:在这个例子中,捕捉块处理要么ArgumentNullExceptionArgumentOutOfRangeException,并将异常实例中称为eArgumentException类型的变量。它不处理除列出的两个以外的任何其他类型的ArgumentException。我认为,as的关联性存在一些混淆。

编辑2:如果列出的例外所有上溯造型到的e类型的变量,则代码完全编译为MSIL没有任何铸模或显式的类型检查,使其更快(潜在显著)比当前语法如果它不是你想要的两个之一,则捕获ArgumentException后跟一个throw;。如果你抓到Exception并检查两种可能的类型来处理和重新投掷,如果它是别的东西,问题就更加明显。

try 
{ 
} 
catch (ArgumentNullException, ArgumentOutOfRangeException as ArgumentException e) 
{ 
} 
+0

能否downvoters说他们为什么downvoted这题? – Dykam 2009-10-07 20:15:58

+1

唯一的问题是“任何人对此有任何意见?”。答案是:“是的,我们大多数人都是非常有见地的人。”要么提出一个“真正”的问题,要么是GTFO。 – abelenky 2009-10-14 21:49:37

+0

[另类,功能风格](http://community.bartdesmet.net/blogs/bart/archive/2008/01/06/exception-handling-in-functional-style.aspx):好吧,还不如干净(作为你的和其他许多建议)**,但这是有效的。** – nawfal 2013-05-18 11:17:36

回答

-1

这只有在您不声明实例(e)时才有效。如果你在块内引用e,它是什么?

+0

'e'显然是'ArgumentException',因为正如我所说它的类型必须是每个列出的处理异常的基类型或接口。除了'ArgumentNullException'和'ArgumentOutOfRangeException'外,catch块不会处理任何'ArgumentException'。我实际上特别提出了这个问题,因为这个语法解决了你提到的问题。 – 2009-10-07 17:15:51

0

我不觉得自己很想在C#中经常使用它,而在Java中,我发现存在各种情况,我必须捕获一堆检查的异常,并将它们全部封装在声明我的方法的不同异常中扔。

东西我可能像一些语法:

try 
{ 
} 
wrap (OneException as AnotherException) 
catch (HandleableException e) 
{ 
    // Actual handling for some exception types 
} 

...但同样,我发现自己这样做比在C#更在Java中。

还有其他的增强功能,其中也一路上涨我名单为C#这:)

+0

这不处理所有'ArgumentException's,只列出了两个。 'as ArgumentException e'给出了'e'类型,这个类型保证与这个catch块声明处理的每一个可能的异常兼容。 – 2009-10-07 17:17:08

+0

你是编辑这个问题,还是我错过了?我可以发誓,它之前只列出了三个例外。嗯 - 编辑:) – 2009-10-07 17:22:38

+0

我没有编辑代码,但我添加了两个标记的段落,解释了为什么这可能比当前更好。有一些API(是ASP.NET吗?),它需要对许多不同类型的异常进行异常处理,而且我看到代码变得非常冗余,没有简单的方法来改进它。 – 2009-10-07 17:31:07

0

你已经可以做到这一点,只是

try{} 
catch(Exception e) 
{} 

,因为所有的异常从System.Exception派生。你会像上面那样做,确定catch块本身的异常类型。

+0

这是缺乏此功能的解决方法,并且在我添加的链接中对此进行了专门讨论。我在上面添加了** Edit 2 **,以解决为此用例添加语言语法的一个主要好处。 – 2009-10-07 17:33:54

+0

Wokrarounds现在工作,您要等待多长时间才能添加语言功能?假设它会一直发生? – 2009-10-07 17:39:58

+0

但这不是这个问题的关键。我已经知道如何处理可用的情况。语言随着时间的推移而发展,呈现出人们所想的特征。这可能永远不会发生(功能接受的统计速率非常低),但至少对我来说这是需要思考的问题。 :) – 2009-10-07 19:20:12

3

看到这个:
Cool or Stupid? Catch(Exception[NamingException, CreateException] e)

我这个问题的答案是,他们应该让你“堆栈”他们喜欢用块:

try 
{ 
} 
catch (ArgumentNullException e) 
catch (ArgumentOutOfRangeException e) 
catch (ArgumentException e) 
{ 

} 

虽然我看你会为而不是。我个人并不认为方法非常有用,因为您已经受限于真正的非接口异常类型,并且没有双重继承。

+0

我喜欢这种方法,因为它模仿如何堆叠病例陈述。只要编码器愿意根据需要确定catch块中的类型。 – 2009-10-07 17:16:08

+0

检查我的两个编辑,再加上这并没有解决“e”是什么类型的问题。 – 2009-10-07 17:28:50

+0

我认为这会起作用,但参数上的变量名应该是唯一的。 – 2009-10-07 17:33:22

0

如果ArgumentNullExceptionArgumentOutOfRangeException有不同的接口,将正确地蒙上了痛苦;

例如ArgumentOutOfRangeExceptionActualValue财产;如果你不得不使用它,你会喜欢的东西结束:


if(e is ArgumentOutOfRangeException) 
{ 
    // use e.ActualValue 
} 
else 
{ 
    // use e.Data 
} 
+0

这是针对每个处理的异常类型共享catch块中的大部分或全部代码的情况。 – 2009-10-07 17:32:19

1

纳入这一功能的是planned对Java 7的语法如下:

try { 
    return klass.newInstance(); 
} catch (InstantiationException | IllegalAccessException e) { 
    throw new AssertionError(e); 
} 

编辑:我觉得目的是对于e的静态类型来说,它是列出的异常的最具体的共同超类。 (在Java中,只有类java.lang.Throwable的实例可以被抛出,因此具有共同的超级接口赶上用途有限的,因为异常不能被再次抛出。)

+0

该提案定义不明确,因为它没有解决向变量'e'提供静态有效类型的主要问题。被处理的异常列表(在''后面用','和Java提议中的'|'分开)应该与异常变量声明类型分开。我用'as'来清楚地区分两者。 Java提议可以使用'as',或者'catch(InstantiationException | IllegalAccessException:VariableType e)',*必须*异常列表中的每种类型都可以转换为'VariableType'。 – 2009-10-07 22:06:25