Cost of Custom Exceptions
I've read that throwing exceptions is an expensive operation. However, doesn't creating your own exceptions make your开发者_StackOverflow code more expressive and readable?
Some of my coworkers suggest that you should just use System.Exception and insert your custom text into the message instead of creating a new custom exception.
I'm interested in other opinions. Appreciate any suggestions.
Do not throw System.Exception
. Ever.
The problem with it resides in the calling code. It is a bad practice to catch the general Exception
object for many reasons. If you throw an instance of the Exception
base class, then calling code has no choice but to catch Exception
if they want to handle it. This forces the calling code to use a bad practice.
Also, the calling code has no reliable means of distinguishing what the exception was, if all it gets is Exception
.
It is typically best to use one of the pre-defined exceptions if any are applicable (ArgumentException
, InvalidOperationException
, etc.). If none correctly describe the situation, then a custom exception class is a perfectly good way to go.
It's the overhead of throwing an exception itself (creating the object, walking the stack, etc.) that's costly. Making your own exception class adds almost no overhead, so if you're going to throw an exception, don't make it new Exception("message")
!
Exceptions aren't meant to be read by people (though their messages and stack traces are read by people), they're meant to be read by code. If there's something your code can do in response to a custom exception, by all means go for it. But the exception is just destined to be logged, there's no point to making a custom one.
The overhead of custom exceptions is that they're another thing to maintain and test. If an existing exception is suitable, use that instead. (E.g., ArgumentNullException
instead of ZipCodeNullException
.)
- If there's any reason for your exception to be caught and handled differently from standard Exceptions, then you should create your own class.
- If there's any reason for your exception to take different arguments (e.g. to produce a specially-formatted message based on a set of arguments that you're often likely to have), then you should create your own class.
In any other case, you're safe just using Exception
. Generally speaking, it doesn't really cost any more to instantiate or throw a custom exception than a standard one, at least not compared with the expense of throwing an exception in the first place. Exceptions, by definition, should be exceptional, and therefore performance during the throwing of an exception is a non-issue. The point is to have all the information you need when the time comes to look at why that exception was thrown.
You should never throw a System.Exception
, because then the only way to catch is is by catch(System.Exception)
. It's very bad practice to catch a blanket exception like that. You should catch specific exceptions, which give you a way to properly handle it without crashing the software. By generating custom exceptions, you give yourself a way to potentially recognize and recover from them.
For example, if your code means to open a file, and you get an unknown exception, how do you recover from it? However, if you catch a specific File Not Found exception, that is much easier to recover from. You can tell the user definitively that the file doesn't exist.
I don't see a reason to believe that custom exceptions are any more expensive than the built-in ones.
"Expensive" is a relative term and - as the name already suggests - an exception should be an exception, so it will probably not affect the performance of your code. The cost of throwing an exception is - as far as I know - independent of the type of the exception, so you should not restrict yourself to System.Exception.
But most important: http://c2.com/cgi/wiki?PrematureOptimization
I prefer to use the most appropriate built in exception, and if that doesn't already exist, derive my own from System.ApplicationException.
I wouldn't recommend throwing System.Exception with a custom message.
Your coworker is talking nonsense. Throwing an exception is the same cost regardless of the class.
And to be honest, all this talk of "expensive" exceptions - yes they are more expensive than a null check or some such, so don't ever use them as a replacement for some sanity check, but they should be encouraged where they make sense (like IOException for example, that's an excellent use case for them - problems with I/O are an exceptional case and they usually must be handled outside of normal program flow).
精彩评论