Alexander Molodykh

Order class members using ReSharper

If you need to orger your class members, following you copmany StyleCop rules, you can use ReSharper (Visual Studio plug-in) to achive that.

In my team we are using class members ordering according to the StyleCop Rules Documentation.

Acording to this documentation:

  • Within a class, struct, or interface, elements must be positioned in the following order:
    • Constant Fields
    • Fields
    • Constructors
    • Finalizers (Destructors)
    • Delegates
    • Events
    • Enums
    • Interfaces
    • Properties
    • Indexers
    • Methods
    • Structs
    • Classes
  • Elements of the same type must be positioned in the following order by access level:
    • public
    • internal
    • protected internal
    • protected
    • private
  • All static elements must be placed above all instance elements of the same type.

It sometimes annoys teammembers following this rules. So I made special template for ReSharper's CodeCleanup tool that provides automatic members ordering according to the StyleCop Rules Documentation.

I also add ordering by member name inside of the each member type group.

To use this feature you have to:

  1. Go to ReSharper->Options->Languages->C#->TypeMemberLayouts and copy this template to the field;
  2. Go to ReSharper->Options->Tools->Code Cleanup.
    Add new rule and sign "Reorder type member". I am also sign "Reformat code", "Arrange 'this' qualifier" and "Optimize using directives".

To run code cleanup you can use ReSharper->Tools=>Cleanup Code or use hot key Ctrl-E, C.

Or you can make full solution cleanup if you left click on solution in the solution explorer window and choice "Cleanup Code".

<Patterns xmlns="urn:shemas-jetbrains-com:member-reordering-patterns">
  <!--Do not reorder COM interfaces and structs marked by StructLayout attribute-->
  <Pattern>
    <Match>
      <Or Weight="100">
        <And>
          <Kind Is="interface"/>
          <Or>
            <HasAttribute CLRName="System.Runtime.InteropServices.InterfaceTypeAttribute"/>
            <HasAttribute CLRName="System.Runtime.InteropServices.ComImport"/>
          </Or>
        </And>
        <HasAttribute CLRName="System.Runtime.InteropServices.StructLayoutAttribute"/>
      </Or>
    </Match>
  </Pattern>
  <!--Special formatting of NUnit test fixture-->
  <Pattern RemoveAllRegions="true">
    <Match>
      <And Weight="100">
        <Kind Is="class"/>
        <HasAttribute CLRName="NUnit.Framework.TestFixtureAttribute" Inherit="true"/>
      </And>
    </Match>
    <!--Setup/Teardow-->
    <Entry>
      <Match>
        <And>
          <Kind Is="method"/>
          <Or>
            <HasAttribute CLRName="NUnit.Framework.SetUpAttribute" Inherit="true"/>
            <HasAttribute CLRName="NUnit.Framework.TearDownAttribute" Inherit="true"/>
            <HasAttribute CLRName="NUnit.Framework.FixtureSetUpAttribute" Inherit="true"/>
            <HasAttribute CLRName="NUnit.Framework.FixtureTearDownAttribute" Inherit="true"/>
          </Or>
        </And>
      </Match>
    </Entry>
    <!--All other members-->
    <Entry/>
    <!--Test methods-->
    <Entry>
      <Match>
        <And Weight="100">
          <Kind Is="method"/>
          <HasAttribute CLRName="NUnit.Framework.TestAttribute" Inherit="false"/>
        </And>
      </Match>
      <Sort>
        <Name/>
      </Sort>
    </Entry>
  </Pattern>
  <!--Default pattern-->
  <Pattern>
    <!--Constants-->
    <Entry>
      <Match>
          <Kind Is="constant"/>
      </Match>
      <Sort>
        <Access Order="public internal protected-internal protected private"/>
        <Readonly/>
        <Static/>
        <Name/>
      </Sort>
    </Entry>
    <!--Fields-->
    <Entry>
      <Match>
          <Kind Is="field"/>
      </Match>
      <Sort>
        <Access Order="public internal protected-internal protected private"/>
        <Readonly/>
        <Static/>
        <Name/>
      </Sort>
    </Entry>
    <!--Constructors. Place static one first-->
    <Entry>
      <Match>
        <Kind Is="constructor"/>
      </Match>
      <Sort>
        <Static/>
        <Access Order="public internal protected-internal protected private"/>
      </Sort>
    </Entry>
    <!--Destructors. Place static one first-->
    <Entry>
      <Match>
        <Kind Is="destructor"/>
      </Match>
      <Sort>
        <Static/>
        <Access Order="public internal protected-internal protected private"/>
      </Sort>
    </Entry>
    <!--Delegates-->
    <Entry>
      <Match>
          <Kind Is="delegate"/>
      </Match>
      <Sort>
        <Access Order="public internal protected-internal protected private"/>
        <Readonly/>
        <Static/>
        <Name/>
      </Sort>
    </Entry>
    <!-- Events -->
    <Entry>
      <Match>
        <Kind Is="event"/>
      </Match>
      <Sort>
        <Access Order="public internal protected-internal protected private"/>
        <Readonly/>
        <Static/>
        <Name/>
      </Sort>
    </Entry>
    <!--Enums-->
    <Entry>
      <Match>
        <Kind Is="enum"/>
      </Match>
      <Sort>
        <Access Order="public internal protected-internal protected private"/>
        <Readonly/>
        <Static/>
        <Name/>
      </Sort>
    </Entry>
    <!--Properties-->
    <Entry>
      <Match>
        <And>
          <Kind Is="property"/>
          <Not>
            <Kind Is="indexer"/>
          </Not>
        </And>
      </Match>
      <Sort>
        <Access Order="public internal protected-internal protected private"/>
        <Static/>
        <Name/>
      </Sort>
    </Entry>
    <!--Indexers-->
    <Entry>
      <Match>
        <Kind Is="indexer"/>
      </Match>
      <Sort>
        <Access Order="public internal protected-internal protected private"/>
        <Static/>
        <Name/>
      </Sort>
    </Entry>
    <!--Methods-->
    <Entry>
      <Match>
        <And>
          <Or>
            <Kind Is="method"/>
            <Kind Is="operator"/>
            <HandlesEvent/>
          </Or>
          <Not>
            <Kind Is="destructor"/>
          </Not>
        </And>
      </Match>
      <Sort>
        <Access Order="public internal protected-internal protected private"/>
        <Static/>
        <Abstract/>
        <Virtual/>
        <Override/>
        <Name/>
      </Sort>
    </Entry>
    <!--all other members-->
    <Entry/>
    <!--nested types-->
    <Entry>
      <Match>
        <Kind Is="type"/>
      </Match>
      <Sort>
        <Access Order="public internal protected-internal protected private"/>
        <Static/>
        <Abstract/>
        <Virtual/>
        <Override/>
        <Name/>
      </Sort>
    </Entry>
  </Pattern>
</Patterns>

All rights reserved.