Skip to content
Michael Yu edited this page Dec 10, 2015 · 4 revisions

Dargon Programming Standards

External Tooling

  • Language - We're a C#/.NET codebase.
  • Devenv - VS2015 with ReSharper.
  • Command Line - Git Bash (Git for Windows)

C# Coding Standard

The Basics

  • Cluster code logically. No more than two consecutive newlines permitted.
  • 3 spaces/tab, no newline before opening curly brace. Violation indicates legacy code.
  • Emphasis on reducing line count while maintaining readability.
  • Avoid #region. It's only permitted for fencing interface implementations.
  • Prioritize readability over micro-optimizations.
  • Code should be self-commenting. Comments should explain 'why', not 'what'.
  • Nest collections sparingly.

Class Design

  • Favor immutability and composition over inheritance. Follow SOLID design principles.
  • Constructor's sole purpose is dependency injection. Move work to public void Initialize() method.
  • Avoid nulls. If nulls don't enter our system, we don't need to defensively check for them.
  • Avoid struct. Struct is only permitted for interop e.g. with Windows API.
  • Depend upon abstractions, not concretions. Expose interfaces to classes.

*.cs Layout

[imports]

namespace Upper.CamelCase {
   [Attributes]
   public class ClassName {
      [SingletonStatics (avoid)]
      [Fields]
      [Constructors]
      [Properties]
      [Initializer]
      [Methods]
      [StaticMethods]
      [InnerClasses]
   }
}

Import Guidelines

  • Order alphabetically. Use Resharper's Organize Imports.
using ItzWarty.Collections;
using static [...];
using SCG = System.Collections.Generic;

Singleton Statics

In general, avoid the singleton pattern and favor constructor dependency-injection instead.

Guidelines

  • Singleton statics at top of class definition as integral to understanding class purpose.
  • Static T instance field should be named instance.
  • Instance Getter should be Property T.Instance.

Example

class ClassName {
   private static readonly ClassName instance;
   public static readonly ClassName Instance => GetInstance();
   private static readonly GetInstance() { /* ... */ }
}

Fields

Guidelines

  • Favor immutability via readonly fields.
  • Sort by IsStatic then IsReadOnly then HasFieldInitializer.
  • Break above rules and cluster relevant fields together in larger, SRP-violating classes. Space clusters for readability.

Ordering

private static readonly X field = new X();
private static readonly X field;
private readonly X field = new X();
private readonly X field;
private X field = new X();
private X field;

Constructors

Guidelines

  • Should only be used for dependency injection. Leverage Fody.Constructors.
  • Should do little work. Move work to Initialize() method.
  • Follow Method Guidelines where possible.

Properties

Guidelines

  • Leverage C# 6.0 arrow operator in getters. Favor immutability.
  • Duplicating property and backing field okay. e.g. public string Name => name;
  • Delegate heavy work to Getter method. e.g. public string Path => GetPath();
  • Generally should be fast. E.g. simple field accessors / getters. Avoid heavy computation.

Examples

Initializers

  • For testability, constructor work is moved to the Initialize() method.
  • Initialize() must be called near the object's construction (e.g. Factory). In other words, if you're passed an object, it's already initialized.

Examples

Methods

Our guidelines for methods are conflicting. Use your best judgment.

  • Keep them tiny with clear purposes.
  • Methods must not be tightly coupled to their callers. Don't extract a helper method with parameters specific to the caller.
  • Cluster overloads together. Order overloads from least-to-most complex, so that delegation goes downward in code.

Examples