Order of Items in Classes: Fields, Properties, Constructors, Methods

Order of items in classes: Fields, Properties, Constructors, Methods

According to the StyleCop Rules Documentation the ordering is as follows.

Within a class, struct or interface: (SA1201 and SA1203)

  • Constant Fields
  • Fields
  • Constructors
  • Finalizers (Destructors)
  • Delegates
  • Events
  • Enums
  • Interfaces (interface implementations)
  • Properties
  • Indexers
  • Methods
  • Structs
  • Classes

Within each of these groups order by access: (SA1202)

  • public
  • internal
  • protected internal
  • protected
  • private

Within each of the access groups, order by static, then non-static: (SA1204)

  • static
  • non-static

Within each of the static/non-static groups of fields, order by readonly, then non-readonly : (SA1214 and SA1215)

  • readonly
  • non-readonly

An unrolled list is 130 lines long, so I won't unroll it here. The methods part unrolled is:

  • public static methods
  • public methods
  • internal static methods
  • internal methods
  • protected internal static methods
  • protected internal methods
  • protected static methods
  • protected methods
  • private static methods
  • private methods

The documentation notes that if the prescribed order isn't suitable - say, multiple interfaces are being implemented, and the interface methods and properties should be grouped together - then use a partial class to group the related methods and properties together.

Is there a standard way to organize methods within a class?

StyleCop enforces some things here:

Within a class, struct, or interface, elements must be positioned in the following order:

  • Fields
  • Constructors
  • Finalizers (Destructors)
  • Delegates
  • Events
  • Enums
  • Interfaces
  • Properties
  • Indexers
  • Methods
  • Structs
  • Classes

Furthermore, elements are ordered by access:

  • public
  • internal
  • protected internal
  • protected
  • private

As well as a few other rules:

  • Contants have to appear before fields
  • static elements have to appear before instance elements.

This might be a good baseline to start. As for additional ordering rules, I usually group related methods together.

How to sort classes/fields/methods/properties in a .NET assembly?


it seems I can't change the order of classes within ModuleDefinition.Types property because it's a get-only IEnumerable.

Not quite, it's a get-only Collection<T>.

This means you can change the order of types in it by getting the list of types from the collection, sorting them, clearing Types and finally readding them back. In code:

var assembly = AssemblyDefinition.ReadAssembly(inputPath);

var module = assembly.MainModule;

var sorted = module.Types.OrderBy(t => t.FullName).ToList();

module.Types.Clear();

foreach (var type in sorted)
{
module.Types.Add(type);
}

assembly.Write(outputPath);

How to set initialization order for a properties object?

I would argue that public setter are not appropriate in this particular case. I would suggest using a constructor instead:

public MyClass(double foo, double value) => (Foo, Bar) = (foo, value*foo);
public double Foo {get; private set;}
public double Bar {get; private set;}

Note that I did not call the parameter bar, since that would lead to the expectation that the Bar-property should have the value of the bar parameter.

You might opt to give Bar a default value if you wish. But in general, the constructor should ensure that the type is fully constructed, so any required properties should be injected as constructor parameters.

I would in general not expect that a setter has any complex behavior. Common logic would be things like range checking or to update things that depend on the property. If you need some more complex logic you could add it as a method, this give a hint that the method does more than just setting a property:

public void SetBar(double value) => Bar = value * foo;

Or use a separate property that calculates foo*bar:

public MyClass(double foo, double bar) => (Foo, Bar) = (foo, bar);
public double Foo {get; set;}
public double Bar {get; set;}
public double FooBar => Foo * Bar;

This would by far be my preferred solution since it would be very difficult to get this kind of code wrong. It should be perfectly obvious what all properties does.

What's the best way to layout a C# class?

I tend to use Microsoft StyleCop, which has a set order according to rule SA1201:

Cause An element within a C# code
file is out of order in relation to
the other elements in the code.

Rule Description A violation of this
rule occurs when the code elements
within a file do not follow a standard
ordering scheme.

To comply with this rule, elements at
the file root level or within a
namespace must be positioned in the
following order:

  • Extern Alias Directives
  • Using Directives
  • Namespaces
  • Delegates
  • Enums
  • Interfaces
  • Structs
  • Classes

Within a class, struct, or interface,
elements must be positioned in the
following order:

  • Fields
  • Constructors
  • Finalizers (Destructors)
  • Delegates
  • Events
  • Enums
  • Interfaces
  • Properties
  • Indexers
  • Methods
  • Structs
  • Classes

Complying with a standard ordering
scheme based on element type can
increase the readability and
maintainability of the file and
encourage code reuse.

When implementing an interface, it is
sometimes desirable to group all
members of the interface next to one
another. This will sometimes require
violating this rule, if the interface
contains elements of different types.
This problem can be solved through the
use of partial classes.

  1. Add the partial attribute to the class, if the class is not already
    partial.

  2. Add a second partial class with the same name. It is possible to place
    this in the same file, just below the
    original class, or within a second
    file.

  3. Move the interface inheritance and all members of the interface
    implementation to the second part of
    the class.

Unity should I write first the Serialized Fields variables or the Public variables

From a functional point of view, it doesn't matter. You can order them however you want, it will still work the same.

However, there are coding guidelines most developers adhere to.
Jonathan Wright answered a similar question where he also linked the c# coding guidelines he cited from:

You would order them as follows:

  • Fields
  • Constructors
  • [...]
  • Properties
  • [...]
  • Methods

Within each of these groups order by access: (SA1202)

  • public
  • internal
  • protected internal
  • protected
  • private

So while members with attributes like [SerializeField] are not explicitly listed, I would order them the same way you do, since the [SerializeField] attribute exposes the field to the Unity Editor and makes them accessible from outside.

Best practice: ordering of public/protected/private within the class definition?

In Clean Code, Robert C. Martin advises coders to always put member variables at the top of the class (constants first, then private members) and methods should be ordered in such a way so that they read like a story that doesn't cause the reader to need to jump around the code too much. This is a more sensible way to organize code rather than by access modifier.

One function for two different classes with similar properties


The why

So when you say this:

public void MyMethod<T>(T value) where T: ClassA, ClassB

You're saying that T should be derived from both ClassA and ClassB. Now it would work in this scenario:

public class ClassA
{
public int SomeProperty { get; set; }
}

public class ClassB : ClassA
{
}

public class ClassC : ClassB
{
}

MyMethod<ClassB>(classBValue); // ClassB is a ClassB and is derived from ClassA
MyMethod<ClassC>(classCValue); // ClassC is derived from ClassB, and is indirectly derived from ClassA

But this won't work:

public class ClassA
{
public int SomeProperty { get; set; }
}

public class ClassB
{
public int SomeProperty { get; set; }
}

Because it requires a ClassC that looks like this:

public class ClassC : ClassA, ClassB
{
}

And this could will cause a compile time error because C# doesn't support multiple inheritance. That is to say that, while you can have a class derived from a class that itself is derived from another class, you can't create a class that directly derives from two classes.

The solution

What you can do is declare an interface:

public interface ISomeInterface
{
int SomeProperty { get; set; }
}

And have both the classes implement it:

public class ClassA : ISomeInterface
{
public int SomeProperty { get; set; }
}

public class ClassB : ISomeInterface
{
public int SomeProperty { get; set; }
}

Then if we change our method signature to require that the class implements our interface:

public void MyMethod<T>(T value) where T: ISomeInterface

Then within the method we can access the SomeProperty property of T:

public void MyMethod<T>(T value) where T: ISomeInterface
{
value.SomeProperty *= 2;
}

Try it online



Related Topics



Leave a reply



Submit