7th Chapter: Anomalies
Exceptions are very well integrated with various object-oriented languages.
Exceptions enhance the consistency of the API.
When you report an error with a return value, the error-handling code is always close to the code that may be the error.
It is easier to make the code for error handling global.
Error codes are easily ignored and often ignored.
An exception can contain rich information to describe the cause of the error.
Exceptions allow the user to define handlers for unhandled exceptions.
An exception can contain rich information to describe the reason for the error amount.
Exceptions allow the user to define handlers for unhandled exceptions.
Exceptions help detect.
7.1 Throwing Exceptions
Do not return an error code.
The report operation failed to be put back by throwing an exception.
Consider terminating the process by calling System.Environment.FailFast when the code encounters a serious problem and cannot continue to execute safely, rather than throwing an exception.
Do not use exceptions in the normal flow of control, if you can avoid them.
Consider the performance impact of throwing exceptions. For most applications, throwing 100 of exceptions per second is likely to severely affect performance.
Write documents for all exceptions and use them as part of the contract-if the exception is thrown because it violates its contract when the public member is called (non-system failure).
Do not let public members decide whether to throw an exception based on an option.
Do not use exceptions as return values or output parameters for public members.
Consider using a helper method to create an exception.
Do not throw an exception in the exception filter program.
Avoid explicitly throwing exceptions from a finally block of code. Implicitly throws an exception, which is acceptable when other methods are thrown by other methods to throw an exception.
7.2 Select the appropriate type for the exception thrown
Do not create new exception types in order to notify the use of errors. In this case, the exceptions already in the framework should be thrown.
Consider creating and throwing a custom exception for a program error-if it is handled differently from other exceptions. Otherwise, an existing exception should be thrown.
Do not create a new exception type-if the handling of the error is not different from the exception that is already in the frame. In this case, the exceptions already in the framework should be thrown.
To create a new exception type to convey a unique program error-If you cannot communicate the error through an existing exception in the frame.
Avoid designing APIs that can cause system failures. If this type of failure can occur, you should call Environment.failfast in the event of a system failure and should not throw an exception.
Do not create and use new exceptions just to have your own exceptions.
To use the appropriate, most targeted (lowest-level derived class) exception.
To provide a rich and meaningful error message to the developer when an exception is thrown.
Make sure that the syntax for the exception message is correct.
Make sure that each sentence in the exception message has a period.
Avoid this use of question marks and exclamation points in exception messages.
Do not leak security messages in the exception message without permission.
Consider localizing the exception message thrown by the component-if you want to make the component available to developers who bathe in other languages.
Do not swallow the error when the framework's code captures specific types of indeterminate exceptions (such as System.Exception, System.SystemException, and so on).
Avoid swallowing errors in your application's code when capturing specific types of indeterminate exceptions (such as System.Exception, System.SystemException, and so on).
Do not exclude any special exceptions-if you write a catch block, the purpose is to transfer the exception.
Consider capturing a specific type of exception-if you do understand the cause of the exception in a specific environment, and can react appropriately to the error.
Do not catch exceptions that should not be caught. Typically, exceptions should be allowed to flow upstream along the call stack.
To use try-finally when doing cleanup work, avoid using Try-catch. For well-written exception codes, try-finally are used much more frequently than try-catch.
To use an empty throw statement when catching and re-throwing an exception. This is the best way to keep the exception call stack intact.
Do not use parameterless catch blocks to handle exceptions that are not CLS-compliant (not derived from System.Exception exceptions).
Consider appropriately encapsulating exceptions thrown at lower levels-if lower-level exceptions do not make sense in a higher-level runtime environment.
Avoid capturing and encapsulating exceptions of specific type uncertainties.
To specify an inner exception for an exception when it is encapsulated.
7.3 Use of standard exception types
Do not throw System.Exception or system.systemexceptio exceptions.
Do not capture System.Exception or system.systemexception exceptions in the framework code unless you intend to re-throw them.
Avoid capturing System.Exception or systen.systemexception exceptions, unless they are in the top-level exception handler.
Do not throw system.applicationexception or derive new classes from it.
The invalidaoperationexception exception to throw-if the object is in an incorrect state.
To throw an ArgumentException exception or its subtype when the user passes in an invalid parameter. If you can, try to use the exception type at the end of the inheritance hierarchy.
The ParamName property to be set when throwing an ArgumentException exception or its child class.
To use value as the name of the value implicit parameter in the setter of the property.
Do not let the public API explicitly or implicitly throw an NullReferenceException, accessviolationexception, or IndexOutOfRangeException exception. These exceptions are specifically left to the execution engine to throw, and in most cases they represent a flaw in the code.
Do not explicitly throw an StackOverflowException exception. Only the CLR should be able to explicitly throw the exception.
Do not catch stackoverflowexception exceptions.
Do not explicitly throw an OutOfMemoryException exception. Only the CLR should be able to throw exceptions.
Do not display COMException, executingengineexception, and sehexception exceptions, only the CLR should be able to throw these exceptions.
7.4 Design of custom exceptions
To derive a new exception from a System.Exception or other common exception base class.
Avoid too deep a hierarchy of inheritance.
To use the "Exception" suffix when naming the exception class.
To make the exception serializable. This is necessary in order for the exception to work well across application domains and across remote boundaries.
To provide the following common constructors for all exceptions (at least).
To report security-related messages through an override method of ToString, you must first obtain the appropriate license.
To keep security-related information in a private exception state, and to ensure that only trusted code can get that information.
Consider defining a property for an exception so that additional information about the exception is obtained from the program, in addition to the message string.
7.5 Anomalies and performance
Do not use error codes because exceptions can adversely affect performance.
Consider using the tester-doer pattern in a member to avoid performance problems caused by an exception-if a member can throw an exception in a common scenario.
Consider using the Try-parse pattern in members to avoid performance problems caused by exceptions, which can be thrown by members in common code.
To use the "Try" prefix when implementing Try-parse mode, and the Boolean type as the return type of the method.
To provide a corresponding member that throws an exception for each method that uses the Try-parse mode.
. NET design Specification, Chapter 7th: Exceptions