The focus of this document is on providing a reference for writing C#. It includes naming, structural and formatting conventions as well as best practices for writing clean, safe and maintainable code. Many of the best practices and conventions apply equally well to other languages.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

A C# Developer's Handbook

The focus of this document is on providing a reference for writing C#. It includes naming, structural and formatting conventions as well as best practices for writing clean, safe and maintainable code.

Many of the best practices and conventions apply equally well to other languages.

  1. Goals
  2. Scope
  3. Environment
  4. Improvements
  5. In Practice
  6. Table of Contents
    1. Overview
    2. Naming
    3. Formatting
    4. Usage
    5. Best Practices


This handbook has the following aims and guiding principles:

  • Increase readability and maintainability with a unified style.
  • Minimize complexity with proven design principles
  • Increase code safety and prevent hard-to-find errors through best practices.
  • Maximize effectiveness of coding tools.
  • Accommodate IDE- or framework-generated code.
  • Provide justifications and examples for rules.


This handbook includes:

  • General programming advice and best practices
  • General formatting and style recommendations
  • C#-specific sections


The recommended environment and tools at this time are:

  • Microsoft Visual Studio 2017
  • JetBrains ReSharper 2016.3.2
  • StyleCop 4.7
  • StyleCop by JetBrains extension for ReSharper
  • Cyclomatic Complexity extension for ReSharper
  • EditorConfig
  • C# 7.0

For older versions of Visual Studio and C#, use what you can or refer to older versions of this handbook.


This document is a work-in-progress. Please speak up or contribute if you think there is something missing.

  • If a guideline is not sufficiently clear, recommend a clearer formulation.
  • If you don’t like a guideline, try to get it changed or removed, but don’t just ignore it. Your code reviewer is most likely unaware that you are special and not subject to the rules.

In Practice

Applying the Guidelines

  • Unless otherwise noted, these guidelines are not optional, nor are they up to interpretation.
  • A reviewer always has the right to correct mistakes and aberrations, but is not obligated to do so in every review.
  • Please note issues with the guidelines during a review. These changes should flow into the guidelines if enough parties agree.

The handbook defines the goal. Use iterations and refactoring to incrementally bring the code closer to full compliance.

Fixing Problems in Code

Fix non-conforming code at the earliest opportunity.

  • Fix small and localized errors immediately, in a "cleanup" commit.
  • Always use a separate commit to rename or move files.
  • Create an issue for larger problems that cannot be fixed quickly.

Working with an IDE

Modern IDEs generate code; this is very helpful and saves a lot of work. Within reason, the generated code should satisfy the coding guidelines. If the generated code is not under your control, then it's OK to turn a blind eye to style infractions.

  • Configure your IDE to produce code that is as close to the guidelines as possible. StyleCop and ReSharper are an enormous help.
  • Update names for visual-design elements and event handlers manually, if needed.
  • Write code generators to produce conforming code.
  • Do not update code generated by tools not under your control (e.g. *.Designer files).
  • Use “Format Document” to reformat auto-generated code.
  • Use the highest warning level available (level 4 in Visual Studio) and address all warnings (either by fixing the code or explicitly ignoring them).

Settings files

This repository includes configuration files that set up the rules outlined in this handbook for StyleCop and ReSharper and EditorConfig.

Table of Contents


  1. Terminology
  2. History
  3. References


  1. Characters
  2. Words
  3. Semantics
  4. Case
  5. Grouping
  6. Algorithm
  7. Structure
    1. Assemblies
    2. Files
    3. Namespaces
  8. Types
    1. Classes
    2. Interfaces
    3. enums
    4. Generic Parameters
    5. Sequences and Lists
  9. Members
    1. Properties
    2. Methods
    3. Extension Methods
    4. Parameters
    5. Lambdas
    6. Events
    7. Delegates
  10. Statements and Expressions
    1. Local Variables
    2. Return Values
    3. Compiler Variables


  1. Whitespace and Symbols
    1. Blank Lines
    2. Line Breaks
    3. Indenting and Spacing
    4. Braces
    5. Parentheses
  2. Language Elements
    1. Methods
    2. Constructors
    3. Initializers
    4. Lambdas
    5. Multi-line Text
    6. return Statements
    7. switch Statements
    8. Ternary & Coalescing Operators
    10. Regions


  1. Structure
    1. Assemblies
    2. Files
    3. Namespaces
  2. Types
    1. Classes
      1. Abstract
      2. Static
      3. Inner
      4. Partial
    2. Interfaces
    3. Generics
    4. structs
    5. enums
  3. Members
    1. Modifiers
      1. sealed
      2. internal
    2. Declaration Order
    3. Constants
    4. Constructors
    5. Properties
    6. Indexers
    7. Methods
    8. Extension Methods
    9. Parameters
    10. Optional Parameters
    11. Expression-bodied Members
    12. tuples
    13. Overloads
    14. Virtual
    15. new Properties
    16. Event Handlers
    17. Operators
    18. ref Returns and Properties
  4. Statements and Expressions
    1. base
    2. this
    3. Value Types
    4. Strings
    5. Interpolation
    6. nameof
    7. Resource Strings
    8. Floating Point and Integral Types
    9. Local Variables
    10. Local Functions
    11. var
    12. out variables
    13. Loops
    14. Conditions
    15. switch
    16. Pattern-matching
    17. continue
    18. return
    19. goto
    20. unsafe
    21. Ternary and Coalescing Operators
    22. Null-conditional Operator
    23. throw-Expressions
    24. Lambdas
    25. System.Linq
    26. Casting
    27. checked
    28. Compiler Variables

Best Practices

  1. Design
    1. Abstractions
    2. Inheritance vs. Composition
    3. Interfaces vs. Abstract Classes
    4. Open vs. Closed APIs
    5. Controlling API Size
    6. Read-only Interfaces
    7. Single-Responsibility Principle
    8. Loose vs. Tight Coupling
    9. Methods vs. Properties
    10. Code > Comments
  2. Safe Programming
    1. Be Functional
    2. Avoid null references
    3. Local variables
    4. Side Effects
    5. ”Access to Modified Closure”
    6. "Collection was modified; enumeration operation may not execute."
    7. "Possible multiple enumeration of IEnumerable"
  3. Error Handling
    1. Strategies
    2. Terms
    3. Errors
    4. Bugs
    5. Design-by-Contract
    6. Throwing Exceptions
    7. Catching Exceptions
    8. Defining Exceptions
    9. The Try* Pattern
    10. Error Messages
  4. Object Lifetime
    1. IDisposable
    2. Finalize
    3. Destructors
    4. Best Practices
  5. Managing Change
    1. Modifying Interfaces
    2. Marking Members as Obsolete
    3. Refactoring Names and Signatures
    4. Roadmap for Safe Obsolescence
  6. Documentation
    1. Files
    2. Language
    3. Style
    4. XML Documentation
    5. Examples
  7. Miscellaneous
    1. Generated Code
    2. Configuration and File System
    3. Logging
    4. ValueTask<T>