Chapter 6th of. NET Design Specifications: scalable design,
Chapter 2: scalability design 6th Extension Mechanism
Consider using a non-sealed class that does not contain any virtual or protected members to provide scalability for the framework. The scalability provided by this method is widely welcomed by users, and its overhead is not high.
Consider using protected members for advanced custom solutions.
When analyzing security, documentation, and compatibility, we should treat protected members in non-sealing classes as public members.
Consider using callback functions to allow users to provide custom code to the framework for execution by the framework.
Consider using events to allow users to customize the framework behavior, so that they do not need to have a deep understanding of object-oriented design.
Priority should be given to events, rather than simple callback functions. The reason is that the majority of developers are more familiar with events, and the events are well combined with the automatic completion feature of VS statements.
Avoid using callback functions in APIs with high performance requirements.
Use the new Func when defining an API that uses the callback function <...>, Action <...> or Expression <...> type, instead of using custom delegation.
You need to use Expression <...> instead of Func <...> and Action <...> to measure the delegate time, so as to understand the potential impact on performance.
Understanding that any code can be executed when a delegate is called may cause security, correctness, and compatibility issues.
Do not use virtual members unless you have appropriate reasons and have a clear understanding of the overhead for designing, testing, and Maintaining Virtual members.
Use protected virtual members rather than public virtual members first. Public members should provide scalability by calling protected virtual members (if necessary ).
Do not provide abstraction unless multiple concrete implementations are developed for the abstraction and actual tests have been performed on it through the abstraction API.
Exercise caution when selecting an abstract class or interface.
Consider providing reference tests for specific abstract implementations. Such tests should tell users whether they have implemented the contract correctly.
6.2 base class
Consider defining a base class as an abstract class, even if they do not contain any abstract members. This clearly tells users that the purpose of designing these classes is to allow users to use them to derive their own subclass.
Consider separating the base class from the type used in the main scenario and placing it in a separate namespace. As defined, the base classes are designed for advanced extension scenarios because most users are not interested in them.
Avoid using the "Base" suffix when naming a Base class-if the public API uses this class.
6.3 Seal
Do not seal the class unless you have a proper reason.
Do not declare protected or virtual members in the seal class.
Consider sealing a member when overwriting it.