Kirill’s Whitespace Guidelines for C#

I don’t remember seeing any explicit guidelines on whitespace formatting for C# programs, however it seems that experienced C# developers all format their C# code files in a very similar fashion, as if there are some implicit but widely-accepted rules. In this post, I’ll try to formalize my own rules that I use intuitively when I format C# code. I’ll add more to it as I discover new stuff and correct things based on your feedback.

No two consecutive empty lines

Bad:

    1:  static void Main(string[] args)
    2:  {
    3:      Main(null);
    4:  }
    5:   
    6:   
    7:  static void Foo()
    8:  {
    9:      Foo();
   10:  }

No empty line before a closing curly

Bad:

    1:          Main(null);
    2:   
    3:      }

No empty line after an opening curly

Bad:

    1:  class Program
    2:  {
    3:      
    4:      static void Main(string[] args)

One empty line between same level type declarations

    1:  namespace Animals
    2:  {
    3:      class Animal
    4:      {
    5:      }
    6:   
    7:      class Giraffe : Animal
    8:      {
    9:      }
   10:  }

One empty line between members of a type

    1:  class Animal
    2:  {
    3:      public Animal()
    4:      {
    5:      }
    6:   
    7:      public void Eat(object food)
    8:      {
    9:      }
   10:   
   11:      public string Name { get; set; }
   12:  }

Whereas it’s OK to group single-line members:

    1:  class Customer
    2:  {
    3:      public string Name { get; set; }
    4:      public int Age { get; set; }
    5:      public string EMail { get; set; }
    6:   
    7:      public void Notify(string message)
    8:      {
    9:      }
   10:  }

However every multi-line member must be surrounded by an empty line unless it’s the first or the last member, in which case there shouldn’t be a line between the member and the curly brace.

One empty line after #region and before #endregion

Usually #region should be treated as if it were the first construct from it’s content (in this example, a type member):

    1:  class Customer
    2:  {
    3:      #region Public properties
    4:   
    5:      public string Name { get; set; }
    6:      public int Age { get; set; }
    7:      public string EMail { get; set; }
    8:   
    9:      #endregion
   10:   
   11:      public void Notify(string message)
   12:      {
   13:      }
   14:  }

Within a #region, it’s contents should be separated from the #region/#endregion by a single empty line. Usually #regions contain type members or whole types, less often parts of a method body.

I think these are the major rules that come into mind for now. If I remember more, I’ll update this post. Also, definitely feel free to contribute any corrections/additions and I’ll update the post too. Thanks!