In my opinion regions are a bad idea (and this seems to be a fairly common opinion). Everyone has their own take on how members should be grouped. Someone else's logic is not the same as mine and therefore the benefit of grouping by an inconsistent means is flawed. A colleague also suggested grouping by logical program flow. This seems like a good idea at first, but with experience modern software typically doesn't follow linear patterns, most applications are asynchronous and event driven, leading to many very different lines of execution through a class.
So the best way to consistently order members in a class is by accessor and then alphabetically by member name. (This conincides with Microsoft's Framework Guidelines book and default configuration for StyleCop). Quite often all a consumer knows is the method name, so that's what they are looking for. Also its nice to have the code ordered in the same order as the member selector dropdown on the toolbar. To achieve this I turn to Regionerate. As them name suggests it can be used to create regions in the code, but like all good tools its configurable, and its sorting capabilities are great.
I've been attempting to perfect my Regionerate config xml, and to do this ideally you need a test class with all manner of members.
My Test Class is at the bottom of this post.
And here's my resulting config file so far. (Check my Essential Tools page for the most up to date version of my config).
There are a couple of annoying bugs in Regionerate that creates unavoidable double line spacing between members. It also seems to change the alignment of closing braces by deleting their indenting tabs. Both of these issues can be quickly worked around by using Visual Studio's Format Document feature (Ctrl+K Ctrl+D), and then doing a quick replace (Ctrl+H) for
\n:b*\n:b*\n
and replace with
\n\n
Hit replace 2 or 3 times and its good to go.
namespace Foo.Service.Console { using System; using System.Diagnostics.CodeAnalysis;
public interface IClass1 { void TestMethod(); }
public struct Struct1 { public int Member1; public int Member2; } public class Class1 { public static readonly int PublicStaticReadOnly1 = 5; public static readonly int PublicStaticReadOnly2 = 6; public const double Pi = 3.141; private const double Ei = 9.12335; private static readonly string Field1; private static readonly int Field2; private static readonly double Field3; private readonly string field4; private readonly int field5; private readonly double field6; private string field7; private int field8; private double field9; static Class1() { Field3 = Pi; } public Class1(int parameter) : this() { this.field8 = parameter; } internal Class1() { this.field7 = "Hello"; } public delegate bool Invocation1(int x, int y); internal delegate bool Invocation2(int x, int y, string position); protected delegate bool Invocation3(int x, int y, string position, double offset); private delegate bool Invocation4(double x, double y, string position, double offset); public event EventHandler IsChanging; public event EventHandler IsMorphing; public enum MyEnum { Cyan, Magenta, Yellow, Black, } public static int Property1 { get; set; } public static int Property2 { get; set; } public static int Property3 { get; set; } public int Property4 { get; set; } public int Property5 { get; set; } public int Property6 { get; set; } internal static int Property7 { get; set; } internal static int Property8 { get; set; } internal static int Property9 { get; set; } internal int Property10 { get; set; } internal int Property11 { get; set; } internal int Property12 { get; set; } protected static int Property13 { get; set; } protected static int Property14 { get; set; } protected static int Property15 { get; set; } protected int Property16 { get; set; } protected int Property17 { get; set; } protected int Property18 { get; set; } private static int Property19 { get; set; } private static int Property20 { get; set; } private static int Property21 { get; set; } private int Property22 { get; set; } private int Property23 { get; set; } private int Property24 { get; set; } public static void StaticMethod1() { } public static void StaticMethod2() { } public static void StaticMethod2(int x, int y) { } public static void StaticMethod2(int x, int y, string position) { } public void Method1() { } public void Method1(int x, int y) { } public void Method1(int x, int y, string position) { } public void Method2() { } internal static void Method3() { } internal static void Method4() { } internal static void Method4(int x) { } internal void Method5() { } internal void Method6() { } internal void Method7(int x) { } protected internal void Method8() { } protected internal void Method9() { } protected internal void Method9(int x) { } protected static void Method10() { } protected static void Method11() { } protected static void Method12(int x) { } protected void Method13() { } protected void Method14() { } protected void Method15(int x) { } private static void Method16() { } private static void Method17() { } private static void Method18(int x) { } private void Method19() { } private void Method20() { } private Class5 Method21(int x) { return new Class5(); } public class Class2 { } public class Class3 { } internal class Class4 { } private class Class5 { } } }