Consider | Unsealed classes with no added virtual or protected members as a great way to provide inexpensive yet much appreciated extensibility to a framework. |
Consider | Using protected members for advanced customization. |
Do | Treat protected members on unsealed classes as public for the purpose of security, documentation, and compatibility analysis. |
Consider | Using callbacks to allow users to provide custom code to be executed by the framework. |
Consider | Using events to allow users to customize the behavior of a framework without the need for understanding object-oriented design. |
Do | Prefer events over plain callbacks as they are more familiar to a broader range of developers and are integrated with Visual Studio. |
Avoid | Using callbacks in performance-sensitive APIs. |
Do | Understand that by calling a delegate, you are executing arbitrary code and that could have security, correctness, and compatibility repercussions. |
Do Not | Make members virtual unless you have a good reason to do so and you are aware of all the costs related to designing, testing, and maintaining virtual members. |
Consider | Limiting extensibility to only that absolutely necessary through the use of the Template Method Pattern. |
Do Not | Provide abstractions unless they are tested by developing several concrete implementations and APIs consuming the abstractions. |
Do | Choose carefully between an abstract class and an interface when designing an abstraction. |
Consider | Providing reference tests for concrete implementations of abstractions. |
Consider | Making base classes abstract even if they don't contain any abstract members. |
Consider | Placing base classes in a separate namespace from the mainline scenario types. |
Avoid | Naming base classes with a “Base” suffix if the class is intended for use in public APIs. |
Do Not | Seal classes without having a good reason to do so. |
Do Not | Declare protected or virtual members on sealed types. |
Consider | Sealing members that you override. |