Kirill’s Whitespace Guidelines for C#

Kirill’s Whitespace Guidelines for C#

Rate This
  • Comments 16

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!

  • "I don’t remember seeing any explicit guidelines on whitespace formatting for C# programs"

    Well, Stylecop is trying to enforce these rules. I hope that more and more people will start adopting these.

  • >Usually #regions contain type members or whole types, less often parts of a method body.

    I'd say that a region wrapping a part of a method body should never, ever be encouraged.

  • I do have to ask about the #regions. Do you actually write code like that? When I first saw #regions I thought they sounded like a great tool for organising code. I tried it for a while and found I really didn't like it. I hated not knowing whether I wasn't seeing just a bit of code or a whole lot. I got into the habit of toggling them all open every time I opened a file. But it was too late. Everybody else started doing it and I couldn't persuade them to stop. Now I think they should really just be reserved for files with sections that need to be processed by automated tools.

    Apart from that diversion, I think your guidelines for vertical whitespace fit with what I'd do naturally.

  • Yes, I use regions in my code.

    Not on the method level though - only to group type members. As I usually don't have more than one type per file, I don't have to group types.

    Also, if I have a large type, I usually split it into parts using partial classes and name them like: Drawing.cs, Drawing.Serialization.cs, Drawing.Coordinates.cs, Drawing.Painting.cs, etc.

  • I don't mind seeing a line or two at the end or start of a class, but since those lines are useless you might as well leave them out.

    Like you I place a line between classes, between methods and between properties, except for single-line properties. I do not usually insert lines between fields.

    But unlike you I always allow myself to insert an extra blank line if that either helps to seperate members that belong to a different logical part of a class, or if it increases the readability by making the code less of a wall of text.

    For example, in a Server class I might seperate networking-related fields like a Socket and some networking settings from fields like threads and syncronisation objects.

    I also often insert two blank lines (instead of the usual single line) between a block of methods and a block of properties, so that it's easier to see where the methods end and the properties start. The same goes for inserting two lines between public methods and private methods, so that I can more easily see where the implementation details start.

    I'd rather have a few blank lines too many than a few too little.

  • Thank you for submitting this cool story - Trackback from DotNetShoutout

  • What about a whitespaces within a methods? :)

  • In languages where whitespace does not matter, I honestly don't believe it should be saved with the file back to source control.  The editor should be able to display code using fairly basic rules to suit you.

  • Hey Kirill,

    Do you have any ideas if/when Visual Studio will start shipping StyleCop compliant [template] code? I can understand why the BCL isn't necessarily style-compliant but I believe it's critical to legitimize C# coding standards.

    The strongest push back I have from some people on my team regarding style compliance is "Visual Studio doesn't do it that way".

    Cheers,

    Navid

  • With tools like Resharper and their functionality like Cleanup Code, I'd ask: why bother defining guidelines like this?

  • @Peter:

    Well, firstly, someone has to *write* tools like Resharper ;-) I'm an IDE developer, I have to think about these things.

    Besides, it was fun to observe these things and ask other people about their experiences.

    Finally, a lot of people don't use tools like Resharper. And a great deal of them format their code without any sort of consistency. This blog post hopes to raise awareness about the issue: either use tools like Resharper or format your code yourself.

    You'll be surprised how much poorly formatted code is out there. I've noticed that by default people who just begin to learn how to program don't pay any attention to this, which results in poorly formatted programs.

  • Navid: if you want, feel free to send me a list of where Visual Studio violates these guidelines and I will log all of them as bugs to be fixed.

    Also, feel free to log bugs yourself at http://connect.microsoft.com/visualstudio/feedback, especially after we release Visual Studio 2010 Beta 1.

  • Betty: agreed. Unfortunately the tools aren't there yet. I personally believe that the source code should be stored in a database in pre-parsed state, not text files.

  • I don't agree on the empty lines after #region and before #endregion. If you leave them out, #region/#endregion are more closely related to the things they are grouping. Compare this to a method definition, you wouldn't write:

    void SomeMethod()

    {

       var x = 10;

    }

  • Max, your approach is valid too. My guidelines are only enforced within my team :)

    If your team chooses your way - great. Just be consistent.

Page 1 of 2 (16 items) 12
Leave a Comment
  • Please add 6 and 4 and type the answer here:
  • Post