-
Notifications
You must be signed in to change notification settings - Fork 0
Coding Standard
Michael Yu edited this page Dec 10, 2015
·
4 revisions
- Language - We're a C#/.NET codebase.
- Devenv - VS2015 with ReSharper.
- Command Line - Git Bash (Git for Windows)
- 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.
- 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.
[imports]
namespace Upper.CamelCase {
[Attributes]
public class ClassName {
[SingletonStatics (avoid)]
[Fields]
[Constructors]
[Properties]
[Initializer]
[Methods]
[StaticMethods]
[InnerClasses]
}
}
- Order alphabetically. Use Resharper's Organize Imports.
using ItzWarty.Collections;
using static [...];
using SCG = System.Collections.Generic;
In general, avoid the singleton pattern and favor constructor dependency-injection instead.
- Singleton statics at top of class definition as integral to understanding class purpose.
- Static
T instance
field should be namedinstance
. - Instance Getter should be Property
T.Instance
.
class ClassName {
private static readonly ClassName instance;
public static readonly ClassName Instance => GetInstance();
private static readonly GetInstance() { /* ... */ }
}
- Favor immutability via
readonly
fields. - Sort by
IsStatic
thenIsReadOnly
thenHasFieldInitializer
. - Break above rules and cluster relevant fields together in larger, SRP-violating classes. Space clusters for readability.
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;
- Should only be used for dependency injection. Leverage Fody.Constructors.
- Should do little work. Move work to
Initialize()
method. - Follow Method Guidelines where possible.
- 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.
- 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.
- Dargon.Services.Clustering.Local.ClusteringPhaseFactoryImpl
- Dargon.Processes.Watching.ProcessWatcherServiceImpl
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.