camelCasefor fields and argumentsPascalCasefor types and methods- Avoid contractions and acronyms if it's not common or well-known (e.g.
Html,Jpeg) - Identifiers should be meaningful (e.g.
vertexArrayorloadedPage, noabc,number) - Names:
- Noun for types, fields and properties (e.g.
CarDescription,humanNames,MeatBicycle) - Verb for methods (e.g.
Initialize,UpdateState,MakeGood) - Question for bool fields, properties and methods (
isDisposed,ShouldUpdate,AreValid)
- Noun for types, fields and properties (e.g.
- Conventions:
camelCasefor public and protected fields, variables and method arguments_camelCasefor private and internal fieldsPascalCasefor types, methods, properties and constantsPascalCaseAsyncforasyncmethodsOnPascalCasefor eventsPascalCaseExtensionsfor extension classesIPascalCasefor interfacesTorTPascalCasefor generic argumentsPascalCaseAttributefor attributes
- Always add access modifiers(
public/protected/internal/private). Even to Unity event methods (e.g.Awake(),Start(),Update()etc.) - Use
readonlywhere possible
[public/protected/internal/private] ?[static] ?[readonly/const/override/new]
- Constants -> Static -> Not static -> Nested types
- Fields -> Properties -> Events -> Constructors -> Methods
public->protected->internal->private
- Only spaces are used for indentation, one tab = 4 spaces
- Blocks begin on a new line. Exception for single line block (e.g.
{ get; set; },{ }or{ return 0; })
bool IsValid { get; set; }
void DoNothing() { }
void Initialize()
{
foreach (var element in collection)
{
...
}
}- Multi line statements should start with an indentation level and an operator on every line except first
var result = veryLongArgumentName1
+ veryLongArgumentName2
+ veryLongArgumentName3;
var linqResult = someEnumerable.Select(...)
.Where(...)
.Aggregate(...)
.ToArray();- Nested using statments should be on one indentation level
using (var stream = new Stream(path))
using (var reader = new StringReader(stream))
{
...
}- Long arguments list should be formatted on one line per argument next to method declaration/call
var Method(
string arg1,
string arg2,
string arg
)
{
...
}
Method(
value1,
value2,
value3
);- Should be no spaces:
- before brackets on method declarartion/call
- before
,and; - before
:in named arguments - before and after
.and?. - before and after
?[,[and] - before
?for nullables (e.g.int?) - between any unary operator and argument (e.g.
++,!,(T)) - after
(and before) - after
{and before}in interpolated strings - before and after
<and>in generic types - before parentheses for
nameof(...),typeof(...)anddefault(...) - before and after indentation
- at the end of the line
- Should be space:
- before single line blocks
- before and after
{and}in one line - before and after
=,=>,?? - before and after
:andwherein type declaration - before and after
?and:in ternary expressions - before and after any binary operators
- arithmetical operators (e.g.
+,*) - logical operators (e.g.
&&,||) - relational operators (e.g.
==,<,>=) - type operators (
as,is)
- arithmetical operators (e.g.
- before and after
new - before parentheses in control structures:
for (...),foreach (...),while (...),if (...),catch (...),lock (...)
System.*namespaces- External dependencies (e.g.
UnityEngine,Zenject,Newtonsoft.Json); - Internal dependencies (e.g.
Phygitalism.*,{ProjectName}.*)
- Lines should be no longer than 120 symbols. Better less than 100
- Always specify namespaces for declared types
- Avoid
this.unless absolutely necessary - Every attribute on its own line. Exception for argument attributes
[Attribute1]
[Attribute2]
void SomeMethod() { ... }
void AnotherMethod([Attribute3] object argument) { ... }- Use
nameof(...)instead if"..."
class SomeType
{
string TypeName => nameof(SomeType);
}- Avoid code commenting. Exception for unclear code, that can't be understood without comments.
- Use private fields with attribute
SerializeFieldfor serializable fields
[SerializeField]
private GameObject _someValue;
PascalCasefor asset's names
- Use
varinstead of type in variable declarations. - Replace
publicfields should be replaced with properties - Use expression syntax in methods and properties
string SomeValue => "result";
string CreateString()
=> enumerable.Select( ... )
.ToString();- Use string interpolation to format strings
Console.WriteLine($"My name is {me.Name}");- Split long method call chains to one call per line
- Do not use nested functions
- Do not use
#region - Conditional compilation should be an exception
- https://www.dofactory.com/reference/csharp-coding-standards
- https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/coding-style.md
- https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide
- https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines
- https://referencesource.microsoft.com
- https://github.com/Unity-Technologies/UnityCsReference