Can I remove empty catch with throw?

2019-01-18 18:12发布

问题:

I'm hoping this is straightforward. I work on a large code-base, the overall quality is good, but occasionally you get some of these:

try
{
   // Calls a .NET remoting method.
}
catch
{
   throw;
}

Note there is no finally logic and the catch does not specify any exceptions or do anything other than what I've provided above. However, I know that catching and re-throwing can alter the call-stack in the exception details. What I'm not sure about is if this behaviour is here specifically because of a .NET remoting call.

Is it safe to remove this try-catch? So far as I can see, it is, but I thought I'd double check for any odd behaviour first.

回答1:

As far as I know, catch (Exception ex) { throw ex } resets the stack-trace. And just catch { throw; } does not.

So if you don't perform any additional logic on error, e.g. logging, I don't know any reason to not remove that catch.



回答2:

Rethrowing as you've shown it shouldn't change the call stack, unless there's something very special about remoting exceptions. (I know there are some special aspects, but I don't think they come into play here.) This is the kind of thing which does lose information:

catch(Exception e)
{
    throw e; // Not throw;
}

My guess is that some developer has included this just so they can put a breakpoint on the throw line. I would get rid of it.



回答3:

In certain situations related to code access security the catch-rethrow clause can be a necessary security feature. But I doubt it applies here. Especially since no sane person would use this pattern without adding a comment.

The point of it is to prevent exception filters from running while having increased privileges.

A few related articles:

http://blogs.msdn.com/b/shawnfa/archive/2005/03/31/404320.aspx
http://msdn.microsoft.com/en-us/library/8cd7yaws(v=VS.100).aspx
http://www.pluralsight-training.net/community/blogs/keith/archive/2005/03/31/7149.aspx


Seems to be obsolete since .net 2:
Impersonation and Exception Filters in v2.0



回答4:

While, in most cases, it probably is redundant/unnecessary code, try { .. } catch { throw; } can suppress compiler optimizations and JIT method inlining. This is mostly seen in call-stack traces.

Thus, there "could" be a side-effect that is relied on elsewhere.

Arguably, the 'error' would be in reliance on this implementation detail, especially without explicit documentation about such expected behavior.. and especially since such is not a guarantee.

See Release IS NOT Debug: 64bit Optimizations and C# Method Inlining in Release Build Call Stacks which predated even this old question.

While the code seems redundant, the try-catch code won't be eliminated during compilation either.