• Conditionally including an attribute
• Changing the declared type of variable
• Switching between different namespaces or type aliases in a using directive—
for example:
using TestType =
#if V2
MyCompany.Widgets.GadgetV2;
#else
MyCompany.Widgets.Gadget;
#endif (查看原文)
A consequence of the last point is that a client should never specifically “catch” a contract failure (the ContractException type, in fact, is internal to help enforce that principle). Instead, the client should call the target properly; if it fails, this indicates a bug that should be handled via your general exception backstop (which may include terminating the application). In other words, if you decide control-flow or do other things based on a precondition failure, it’s not really a contract because you can continue executing if it fails.
This leads to the following advice when choosing between preconditions and throwing ordinary exceptions:
• If failure always indicates a bug in the client, favor a precondition.
• If failure indicates an abnormal condition, which may mean a bug in th... (查看原文)