Why does the use of blocks prevent swallowing?

I recently ran into an exception handling problem when using an operator. The problem is that exceptions that are thrown inside a "using block" can be internalized, for example look at the code:

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);
        }
    }
}

      

In this example, you will see "dispose" in the output, the first exception will be ignored and you will never know about it. After some searching, I found an article https://msdn.microsoft.com/en-us/library/aa355056(v=vs.110).aspx about common usage errors using block. But my question is not how to avoid swallowing exceptions, I "want to know why MS decided to expand the block with

try
{
...
}
finally
{
}

      

and not otherwise, for example, they can be unpacked using the following:

//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();

      

+3


source to share


1 answer


Because it AggregateException

didn't exist when the block was created using()

.

Also because you Dispose()

really shouldn't throw yourself.



Finally, because finally

there are subtle semantic differences between your example and the block , regarding exception filters, stack expansion, and critical areas.

+3


source







All Articles