I don't know what we can do with a custom exception, what we can't do with a built-in one. It seems a n开发者_高级运维aive question but I really have no idea about that. What do you think?
The reason for the different types of exceptions is to allow you to be able to catch just the ones you want with your handlers, letting the others go on up the stack. So you can arrange to catch exceptions for certain, occasionally-expected situations just by the type of the exception.
You may not need to create your own very often at all, actually. But if you do, it would be because you need to be able to throw and capture an exception type more specific than what is available, and perhaps with additional information attached.
It is useful to create a custom exception if:
- There is no built-in exception that expresses the type of error condition you have.
- You want to catch only that specific type of exception and not exceptions coming from the framework.
But usually if there already is an exception in the framework that you could use then it is better to use it instead of creating your own exception for the same thing.
You could use it for implementing special error handling for things related to your application. Suppose you build a banana application, then you could have an OutOfBananasException
. If your application gets out of bananas you can throw the exception and catch it later on with special error handling.
try
{
EatBananas();
}
catch(OutOfBananasException oobe)
{
GetMoreBananas();
}
catch(Exception e)
{
TellUserAndAbort();
}
Edit:
The reason to use your own Exceptions instead of the built in is to make it clear to everyone reading you code or using your library what type of error has occurred. You should only create your own exceptions when you can not find any suitable built in exception.
Edit2:
One thing you can do with your own exceptions that you can not do with built in is to add properties describing things about the error condition that the error handler might use. If you have an exception relating to customers you exception could have properties for customer name and customer id and thus make it possible for the error handler to display informative error messages to the user.
There's only a few exceptions in .NET that are treated in a special manner, like ThreadAbortException, which can't (normally) be caught and handled and swallowed.
Other than that, exception types are just exception types. You can do pretty much the same with your own exceptions that you can do with the ones defined in the framework.
The benefits of custom exceptions have been outlined here, but before you create your own make sure the BCL doesn't already have one fitting your needs:
http://mikevallotton.wordpress.com/2009/07/08/net-exceptions-all-of-them/ (There's 141 of them!)
One annoyance with the built-in exceptions is that there is no systematic distinction made between exceptions that indicate that
- an operation failed but a retry might succeed; the system state is as it was before the operation was attempted.
- an operation failed, and a retry isn't likely to help; nonetheless, the system state is as it was before the operation was attempted;
- an operation has failed in such a way as to potentially corrupt something else.
It may be useful to catch exceptions and rethrow one of three custom exceptions (meanings defined above) based upon where the exception was caught. When the exception is rethrown, pass the original exception as the InnerException parameter.
Incidentally, it's possible to define generic exceptions. I'm not quite sure of the pros and cons of doing so, and I've never seen anyone else do it. One could define e.g. a TransientFaultException(of T) which inherits from a (custom) TransientFaultException; an application which catches a TimeoutException could rethrow as a TransientFaultException(of TimeOutException) and have it caught as either a TransientFaultException(of TimeoutException) or a TransientFaultException. Unfortunately, one would have to know the type of the exception to be taught to create the proper generic. If one were to catch an Exception and pass it to a factory method for TransientFaultException, the new exception would be of type TransientFaultException(of Exception), regardless of what type of exception was originally thrown.
Custom exceptions allow you to do 2 things:
- Capture custom typed-data in the exception
- Capture a custom exception occurrence
You should only create a custom exception when there isn't a built in exception to handle as necessary.
As an example, in our application we have DataLayerException
which is thrown when the datalayer encounters an error (and includes the specific DBMS exception as an inner exception).
We also have DataLayerSingleResultNoneException
- which is when we expect a single result back but there is no result, and DataLayerSingleResultManyException
which is when we expect a single result but get many back. This allows us to catch the different problems an action them accordingly.
精彩评论