chi*_*oro 8 c# syntax exception
注意:我很高兴地告诉您,异常过滤器现在使用的是C#6.0语言.
这是一个思想实验,我对你的观点感兴趣:这对你有意义吗?你知道C#编程语言是否已经提出了类似的东西吗?我甚至不知道在哪里提出这样的建议......
这个想法是引入语法元素,只有在满足特定条件时才能捕获异常.
一个用例示例是在使用COM Interop时:一切都会抛出一个COMException.实际区分错误代码包含在其消息中.
那么(提案1):
try
{
...
}
catch (COMException ex where ex.Message.Contains("0x800706BA"))
{
// RPC server unavailable
}
catch (COMException ex where ex.Message.Contains("0x80010001"))
{
// Call rejected by callee
}
Run Code Online (Sandbox Code Playgroud)
转换为:
try
{
...
}
catch (COMException ex)
{
if (ex.Message.Contains("0x800706BA"))
{
// RPC server unavailable
}
else if (ex.Message.Contains("0x80010001"))
{
// Call rejected by callee
}
else
{
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
类似的案例是:SoapException,XmlException......
另一种情况是异常被包装为一般异常中的内部异常,并且捕获逻辑应该依赖于内部异常.
假设我们有一个包含这样的异常的API : catch (NumberFormatException ex) { throw new BusinessException(ex) }.
怎么样(提案2A):
try
{
...
}
catch (inner NumberFormatException nfex)
{
...
}
Run Code Online (Sandbox Code Playgroud)
转换为:
catch (Exception ex where ex.InnerException is NumberFormatException)
{
NumberFormatException nfex = ex.InnerException;
...
}
Run Code Online (Sandbox Code Playgroud)
或(2B):
catch (BusinessException bex inner NumberFormatException nfex)
{
...
}
Run Code Online (Sandbox Code Playgroud)
转换为:
catch (BusinessException bex where bex.InnerException is NumberFormatException)
{
NumberFormatException nfex = bex.InnerException;
...
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下(最初来自Java)它看起来像(2C):
catch (RemoteAccessException raex inner inner MyException mex)
{
...
}
Run Code Online (Sandbox Code Playgroud)
小智 22
根据Visual Studio 2015 RC的try-catch C#参考,现在实现了:
Catch (ArgumentException e) when (e.ParamName == "…")
{
}
Run Code Online (Sandbox Code Playgroud)
VB.Net具有异常过滤器的这一功能,如下所示
Catch ex As COMException When ex.ErrorCode = 0x800706BA
Run Code Online (Sandbox Code Playgroud)
所以这得到了CLR的支持,但是这个功能没有在C#中公开
据说F#也有这个功能,但我不太了解F#来展示例子.
从 c# 7.0 开始就已经支持这种东西了。这是完整的参考。这是代码片段。
try
{
SomeOperationThatThrowsException();
}
catch(TheFilteredException ex ) when (ex.ErrorCode==123)
{
DoSomethingWhenExceptionThrown();
}
Run Code Online (Sandbox Code Playgroud)
异常和类型紧密相关。如果要区分两种不同类型的异常,则应该创建两种异常类型。在您的示例中,您将有一个 Com800706BAException 和一个 Com80010001Exception。
现在,这并不总是可能或可行的,例如,如果底层系统使用错误代码而不是异常。在这种情况下,您的方法可能会有所帮助。然而,这种语言特性很容易被滥用。例如,您可以像这样进行错误处理,这不是类型安全的:
catch (Exception e where e.Message = "The foo barfed up the bar")
Run Code Online (Sandbox Code Playgroud)
如果您想检查异常的内部异常,那么您正在错误的级别上进行错误处理。这个想法是,方法抛出一个通用异常,将调用者从方法的内部工作中抽象出来。如果您依赖于某些内部异常,那么您将与该方法的实现紧密耦合。这不好。
要么应该抛出一个单独的通用异常,要么应该将错误处理移到方法内部。
| 归档时间: |
|
| 查看次数: |
11859 次 |
| 最近记录: |