Csharp Style Guide

From Pearhub Wiki
Revision as of 08:20, 5 November 2021 by Steven (talk | contribs) (Created Page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

In order to make sure that our code-base is uniform and doesn't become a hodgepodge of different coding styles, all programmers should write code that conforms to rules detailed on this page.

Note that some parts of this Style Guide are taken directly from Google's C# Style Guide.

If you want to add rules to this style guide, start a discussion first.

Formatting

Indentation and Spacing

  • Use 1TBS.
  • Maximum of one statement per line.
  • Break up long method parameter-lists by writing one parameter per line e.g.
public void MethodWithABunchOfParameters(int a,
                                         int b,
                                         int c,
                                         int d,
                                         int e) {...}

Names

The names of C#-script-files should always be the name of the main class in the file, e.g. MyClass.cs is the name of a file with a class MyClass.

Style When to use Examples
PascalCase
  • classes
  • enumerations
  • namespaces
  • public methods
  • fields intended for public use
  • class MyCoolClass {...}
  • enum DaysInWeek {...}
  • namespace TheNamespace {...}
  • public void Foo() {...}
  • public static Master Instance;
camelCase
  • local variables
  • parameters
  • fields intended for private use
  • int myInteger;
  • public void Foo(int firstParameter, int secondParameter) {...}
  • public Company owner;
  • For casing, a “word” is anything written without internal spaces, including acronyms. For example, MyRpc instead of MyRPC.
  • Names of interfaces start with I, e.g. IInterface.
  • A Singleton-Instance field must always be names Instance

Usage-indicating prefixes

Prefix Indicates Examples

_

field should not be directly written to. Setter should be used

public BuildingType _type;

pf

variable is a Prefab

public GameObject pfBuilding;

go

variable is of type GameObject

public GameObject goBuildings;

t

variable is of type Transform

public Transform tBuildings;

Organization

  • Modifiers occur in the following order: public protected internal private new abstract virtual override sealed static readonly extern unsafe volatile async.
  • Namespace using declarations go at the top, before any namespaces
  • Class member ordering:
    • Group class members in the following order:
      • Nested classes, enums, delegates and events.
      • Static, const and readonly fields.
      • Fields.
      • Constructors and finalizers.
      • Methods.
    • Within each group, elements should be in the following order:
      • Public.
      • Internal.
      • Protected internal.
      • Protected.
      • Private.
    • Where possible, group interface implementations together.

Coding Guidelines

Getters and Setters

Getters

Don't use getters only to return a private variable. If you need to access a variable in another class, make that variable public.

'Convenience'-getters that simplify complex operations, e.g. ServerDatabase.GetCompanyIdOf(int playerId), should be used.

Setters

Only use setters when necessary, don't preemptively add setters to every member variable just in case.

If it turns out a member variable needs a setter, prefix it with a _ (underscore). Then fix all the compile-errors by replacing writes with your setter, and adding the underscore to reads.

Private Member Variables

Most (if not all [TBD]) member variables should be public. See Getters and Setters.

Properties

Never use properties, ever. They introduce hidden control-flow and quickly become unmanageable. (See Also: Getters and Setters)

Constants

  • Variables and fields that can be made const should always be made const.
  • If const isn’t possible, readonly can be a suitable alternative.
  • Prefer named constants to magic numbers.

The var keyword

The var keyword should only be used if the type of the object that is being declared is explicitly written in the same line as the declaration.

This is for making code easily-readable, as well as decreasing very hard-to-pin-down bugs that can arise because a method returns an unexpected type or when a method changes it's return type.

Examples:

  • Good:
    • var building = new Building(...); We know that building must be of type Building
  • Bad:
    • var employees = myBuilding.GetEmployees(); May return an array, List, Dictionary, etc.
    • var goBuilding = GameObject.Instantiate(Master.Instance.PfBuilding); May be confused with Object.Instantiate, or vice-versa.


Basically, only use var if a new follows.