Saturday, July 5, 2008

.NET Type Design

Namespaces

  • The main purpose of namespaces is to organize types in a hierarchy that is coherent, easy to navigate, and easy to understand.

  • Split out types of advanced functionality into a namespace under the namespaces that contains the simple types.

  • If you have functionality that should be in the same namespace, but you don’t think it needs to be shown all the time to users, you can use the EditorBrowsable attribute. Put this attribute on a class or member and you can instruct Intellisense to only show the class or member for advanced scenarios.

  • Namespace cannot prevent naming collision. Namespaces are a language thing. The CLR doesn’t know anything about them really.

  • If you define a class with same name and same assembly in another assmbly, and then build an application that uses both of these assemblies and types. The CLR would not get confused because the type identity in the CLR is based on strong name (which includes fully qualified assembly name) rather than just the namespace and type name.

Abstract class vs Interface



Interface Design

  • Avoid interfaces with more than 6 methods. If more methods are required, consider creating base interfaces from which you derive more complex interfaces. Example: IList, ICollection, IEnumerable.
  • When writing an application that uses .NET remoting, an interface can be a better and cleaner choice than abstract class.

Abstract Class

  • Use the Base suffix for abstract types. Many abstract types in the .NET Framework follow this guideline such as CollectionBase, DictionaryBase, WebPartZoneBase.

Static Class

  • A static class is a sealed class that has a private constructor and has only static fields, properties and methods.
  • When a class is declared as static, it is sealed, abstract and no instance members can be overridden or declared.
  • You cannot define a static structure, because structures (value types) can always be instantiated no matter what. Only classes can be static.
  • A static class is typically used to achieve one of the following goals:
    • To implement the singleton design pattern. E.g. the console class, you only need one console window.
    • To provide a container for methods. E.g. System.Math class.
    • To provide a container for global variables in the current application.

Nested Types

  • A nested type is a type defined within the scope of another type.
  • The outer type is called the enclosing type.
  • A nested type has access to all members of its enclosing type such as private fields.
  • A type should be nested if it is used only by the enclosing type. So use a private or internal scope qualifier for nested types. Nested enumerators and comparers can be given public scope.
  • Example: the enumerator of a collection can be a nested type of that collection. Enumerators are usually instantiated by their enclosing type and because of the foreach statement, enumerator variables rarely have to be declared by the end user.
  • When to use:
    • Organizing code into real world situations where there is a special relationship between two objects.
    • Hiding a class within another class so that you do not want the inner class to be used from outside of the class it is created within.
  • Do not define a nested type as a member of an interface. Many languages do not support such a construct.

Reference:

Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries

Design Guidelines for Developing Class Libraries

Practical Guidelines and Best Practices for Microsoft Visual Basic and Visual C# Developers

Nested Classes

blog comments powered by Disqus