Naming Classes That Implement an Interface

Problem
You’re interested in guidelines for naming interfaces.

Solution
1. Use the Comparer suffix for types that implement the IComparer interface. Example: AccountComparer.
2. Use the Formatter suffix for types that implement the IFormatter interface. Example: AccountFormatter.
3. Use the interface name (without the I prefix) when defining a type whose only purpose is to implement an interface.

Comments
Let’s expound upon guideline #3 above. Here’s an example. If you have a class that implements the IWebDriver interface, you might name it BlazingFastWebDriver.

Language-Specific Keywords

Question
What’s the best way to specify the type of type members?

Answer
Use language aliases when specifying the type of fields, properties, and methods. For instance, use int instead of Int32 or System.Int32.

Comments
Using this convention is best because it’s more common and natural. Additionally, code editors render language-specific types in a different color. This improves code readability.

Examples

// Valid C#, but not ideal.
private Int32 age;

// The preferred method.
private int age;

// Alternative approach that includes a type suffix in the method name.
// Works, but not great since the type doesn't match the method name.
public int GetDataInt32()
{
    return ...
}

// Better.
public Int32 GetDataInt32()
{
    return ...
}

Member Names and Case Sensitivity

Question
Is it okay to give type members names that differ only in their casing?

Answer
You never want to define public members using names that differ only in their casing. You should also avoid giving private members names that differ only in their casing.

Comments
Why? It’s harder to read code when names differ only in their case.

Examples

class User
{
    // Not good. Two properties that only differ in case.
    public string UserName { get; set; }
    public string userName { get; set; }
}

class Card
{
    // Also not good. Two methods that only differ in case.
    public int Count()
    {
        ...
    }

    public int count()
    {
        ...
    }
}

Abbreviations and Acronyms in Identifiers

Problem
You want to know the rules for using abbreviations and acronyms in type and member names.

Solution
Follow these guidelines to determine how you should use abbreviations and acronyms:

1. Avoid abbreviations in type and member names.
2. Only use acronyms if they are well known by developers (e.g. UIThread).
3. Two-character acronyms should use an all-uppercase style.
4. Use PascalCase for acronyms with three or more characters.

Comments
These conventions come from Microsoft, but you may notice that some classes in the .NET Framework do not follow them. For example, ASCIIEncoding and CLSCompliant.

Namespace-Qualified Types

Problem
You want to know if you should use fully qualified names when working with types in your code.

Solution
You’ll want to avoid using fully qualified type names. Make statements shorter by placing using statements at the top of source files.

Comments
There’s a nice convention to follow with using statements. List all .NET namespaces first and then ones imported from third-party libraries. In addition, always list nested namespaces after their enclosing one.

Example

using System;
using System.Timers; // Nested namespace.
using OpenQA.Selenium; // 3rd-party namespace.

Type Dependencies in Nested Namespaces

Problem
You want to know the rules for type dependency in namespaces.

Solution
It’s okay for types in a nested namespace to depend on types in an enclosing namespace. However, it’s not okay for types in an enclosing namespace to depend on those in a nested one.

Comments
For example, types in System.Web.UI.WebControls depend on types defined in System.Web.UI, but types in System.Web.UI don’t depend on those defined in System.Web.UI.WebControls.