4th: Type Design specification 4.1 types and namespaces
Namespaces are used to organize the types into a hierarchy of related functional areas.
Avoid a very deep namespace hierarchy. This level of browsing is difficult because users often need to look back.
Avoid having too many namespaces.
Avoid placing types that are designed for advanced scenarios and types that are designed for common programming tasks in the same namespace.
Do not define a type without specifying the type's namespace.
To put the types that provide design-time functionality for the base namespace in the band. Design suffix in the namespace.
To put those types that provide custom permissions for the base namespace in the band. Permissions "suffix in the namespace.
To put the types that provide interoperability functionality for the basic namespace in the band. Interop "suffix in the namespace.
To put all the code in the primary interop assembly in the band. Interop "suffix in the namespace.
4.2 Choice between class and structure
Consider defining the structure rather than defining the class-if the instance of the type is small and the declaration period is shorter, or is often embedded in other objects.
Avoid defining structures unless the type has all of the following characteristics.
It logically represents a separate value, similar to the base type (int, double, and so on);
The size of its instance is less than 16 bytes;
It is immutable;
It does not need to be boxed often.
4.3 Selection between classes and interfaces
To prioritize classes rather than interfaces
The coupling between the contract and the implementation is to be lifted with an abstract class rather than an interface.
To define an interface-if you need to provide a value type for a polymorphic hierarchy.
Consider defining an interface to achieve a similar effect to multiple inheritance.
4.4 Design of abstract class
Do not define a public or internal protected constructor in an abstract type.
To define a protected constructor or intrinsic constructor for an abstract class.
To provide at least one specific type that inherits from the abstract class for each abstract class.
4.5 Design of Static class
Try to use as few static classes as possible.
Do not treat static classes as clutter bins.
Do not declare or overwrite instance members in a static class.
To define a static class as sealed, abstract, and add a private instance constructor-if the programming language does not directly support static classes.
4.6 Design of the interface
To define an interface-if you want a set of types, including value types, to support some common APIs.
Consider defining an interface-if you want a type that has been inherited from another base class to support the functionality provided by that interface.
Avoid using a token interface (an interface with no members).
To provide at least one type that implements the interface for the interface.
To provide each interface with at least one API that uses the interface (a method that takes that interface as a parameter, or a property of that interface).
Do not add members to an already issued interface.
4.7 Design of the structure
Do not provide a default constructor for the struct.
Do not define a mutable value type.
To ensure that all data for a struct instance is 0, false, or null (if appropriate), the structure is still in a valid state.
To implement iequatable<t> for a value type.
Do not explicitly extend System.ValueType, in fact most programming languages do not allow this.
4.8 Design of enumerations
To use enumerations to strengthen the parameters, properties, and the type of the return value of the collection that represents the value.
Instead of using static constants, use enumerations first.
Do not use enumerations for open collections (such as the version of the operating system, the name of a friend, etc.).
Do not provide enumeration values that are reserved for future use.
An enumeration that avoids exposing only one value to the display.
Do not include Sentinel values in the enumeration.
To provide a 0 value for a simple enumeration type.
Consider using Int32 as a vector to implement enumerations (the default choice for most programming languages), unless any of the following is true.
To name a tag enumeration with a plural noun or noun phrase, use a singular noun or noun phrase to name a simple enumeration.
Do not expand System.Enum directly.
To use System.FlagsAttribute for tag enumeration. Do not use this modifier property for simple enumeration.
Use the power of 2 as the value of the tag enumeration so that you can use a bitwise OR operation to freely assemble them.
Consider providing special enumeration values for common tag combinations.
Avoid having a tag enumeration created that contains some invalid combinations.
Avoid using 0 as the value of the tag enumeration, unless the value means "all tokens are cleared" and is properly named according to a specification.
To name the 0 value of the tag enumeration as None. For a tag enumeration, the value must always mean "all tokens are cleared."
Consider adding a value to the enumeration, despite the risk of a bit of compatibility.
4.9 Nested types
Use nested types when you want a type to have access to members of the outer type.
Do not use a common nested type for logical grouping, you should use a namespace to achieve this purpose.
Avoid exposing nested types publicly. Unless you declare a variable of a nested type in only a few cases, such as derived subclasses, or other high-level scenarios that require customization.
Do not use a nested type-if the type may be referenced by a type other than its outer type.
Do not use nesting-if you need to have customer code instantiate them. If a type has a public constructor, then he should not be nested in another type.
Do not define nested types as members of interfaces, and many programming languages do not support this.
4.10 Type and assembly meta data
The CLSCompliant (true) Adornment property is used in assemblies that contain public types.
To use the AssemblyVersionAttribute decorated property in assemblies that contain public types.
Consider using the format of <V>, <S>, <B>, <R> in the assembly version number. Where V is the major version number, S is the service version number, B is the build number, and R is the build revision number.
To use the following decorated properties in an assembly, provide additional information.
Consider using ComVisible (false) in an assembly. APIs that are available for COM calls need to be specifically designed.
Consider this use of AssemblyFileVersionAttribute and assemblycopyrightattribut in assemblies, which is intended to provide additional information about the assembly.
". NET Design Specification" Chapter 4th: Type Design Specification