Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么要使用块和异常?_C#_.net_Using Statement - Fatal编程技术网

C# 为什么要使用块和异常?

C# 为什么要使用块和异常?,c#,.net,using-statement,C#,.net,Using Statement,我最近在使用语句时遇到了异常处理问题。问题在于,在“using block”中抛出的异常可能会被吞没,例如查看代码: class DisposableObject : IDisposable { public void Dispose() { throw new Exception("dispose"); } } class Program { static void Main() { try {

我最近在使用语句时遇到了异常处理问题。问题在于,在“using block”中抛出的异常可能会被吞没,例如查看代码:

class DisposableObject : IDisposable
{
    public void Dispose()
    {
        throw new Exception("dispose");
    }
}

class Program
{
    static void Main()
    {
        try
        {
            using (var obj = new DisposableObject())
            {
                throw new Exception("using");
            }
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}
在本例中,您将在输出中看到“dispose”,第一个异常将被忽略,您永远不会知道它。经过搜索,我找到了一篇关于使用block的常见错误的文章。但我的问题不是如何避免异常吞咽,我想知道MS为什么决定使用块来打开包

try
{
...
}
finally
{
}
而不是其他,例如,他们可以使用以下方式展开:

//this code prevents exception swallowing
try
{                       
    ...
}
catch (Exception ex)
{
    try
    {
        if (obj != null)
            obj.Dispose();
    }
    catch (Exception disposeEx)
    {
        throw new AggregateException(ex, disposeEx);
    }

    throw;
}
if(obj != null)
    obj.Dispose();

因为创建
using()
块时,
aggregateeexception
不存在

还因为
Dispose()
实际上不应该抛出


最后,因为您的示例和
Finally
块在异常过滤器、堆栈展开和关键区域方面存在细微的语义差异。

它们可能创建了AggregateException。我不认为AggregateException的缺失是个问题,它是一个非常简单的类。另外,如果Dispose确实不应该抛出异常,但事实上Dispose可以在许多流行的库中抛出异常,例如WCF(客户端代理可以在disposing时抛出异常)。第三,我刚刚编写了示例代码,演示了如何避免吞咽,它可以用finally block编写(我想我可能错了)。这是一个聪明的问题。他们本可以这样做以防止错误丢失。Wait也有类似的问题。除了一个错误(通常不确定是哪一个错误)之外,它会丢弃所有错误。@usr使用代码中未出现的不同类型创建新异常似乎有问题。早些时候,C#有一个“毫不意外”的设计,尽管现在肯定已经放松了。@mikez Alternative,他们可以在第二个异常上将第一个异常放入某些属性中。