- Try and avoid using
var. While the C# type inference is impressive, I think being as explicit as possible when writing is the best route to go. Only usevarif it's painfully obvious. - Use
constas much as possible. If the value has to be cacluated at runtime, then usereadonly. The less we're changing variables, the easier it is to follow and debug. - Try to keep variables as localized as possible. For example, if a variable is only within a function, then keep it there. There is no need to make it a member. If another function/method needs it, then try and pass it from one function to another. Sometimes this is unavoidable, but try your best to do this.
| Nomenclature | Casing | Example |
|---|---|---|
| Namespace | PascalCase | GnuPlusLinux |
| Classes | PascalCase | public class HomeController |
| Functions & Methods | PascalCase | private int TotalUsers() |
| Public Fields | camalCase | public int myInt |
| Private/Protected Fields | camalCase w/ _ prefix |
private int _myPrivateInt |
| Static/Readonly/Constants | PascalCase | public const Title |
| Local Variables | camalCase | bool myBoolean |
| Function Parameters | camalCase | private int GetStringLength(in int myString) |
- Imports should be ordered alphabetically and organized by .NET/external dependencies first and project imports second.
- Only include imports that are used. If an import is not used, then please remove it.
Bad:
using GnuPlusLinux;
using System.Data.SqlClient;
using System;
using System.Data;
using GnuPluxLinuxDAL;
using System.Linq;
using System.Collections.Generic;Good:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using GnuPlusLinux;
using GnuPluxLinuxDAL;
- Use Allman Style Braces.
Bad:
if (condition) {
Console.WriteLine("Hello");
}
if (condition)
{
Console.WriteLine("Hello");
}
if (condition) {
Console.WriteLine("Hello"); }Good:
if (condition)
{
Console.WriteLine("Hello");
if (nextCondition)
{
Console.WriteLine(" World!");
}
}
else
{
Console.WriteLine("Hello World!");
}
- Lines should not exceed 80 columns.
- Use four spaces for indentation.
Bad:
public void BadSayHello()
{
// Two tabs
Console.WriteLine("Hello!");
}
public void BadSayHelloAgain()
{
// Two spaces
Console.WriteLine("Hello!");
}Good:
public void GoodSayHello()
{
// Four spaces
Console.WriteLine("Hello!");
}
- Use four spaces for line wrap indentation too.
Bad:
VeryVeryLongType thisLongType = LongFunctionNameToGrabType(which, takes, many, arguments).GetSomeObjectFromType();
/* OR */
VeryVeryLongType thisLongType =
LongFunctionNameToGrabType(which, takes, many, arguments)
.GetSomeObjectFromType();Good:
VeryVeryLongType thisLongType =
LongFunctionNameToGrabType(which, takes, many, arguments
.GetSomeObjectFromType();
- Always specifiy the visible whenever possible, even if the default is correct.
Bad:
class NewClass
{
int x;
int _y;
}Good:
internal class NewClass
{
public int x;
private int _y;
protected int _z;
}
- As best as you can, try and keep the condition checks affirmative instead of negative. It just makes it easier to follow the logic rather than having to flip the condition in your head.
Bad:
if (!string.IsNullOrEmpty(myString))
{
// Proceed with function
}
else
{
// Call subroutine to get myString
}Good:
if (string.IsNullOrEmpty(myString))
{
// Call subroutine to get myString
}
else
{
// Proceed with function
}
- Please use the keywords
out,in, andrefas much as possible. The more descriptive you can be in a function signature, the easier it is to follow.
Bad:
private int GetStringLength(string str)
{
// code
}Good:
private int GetStringLength(in string str)
{
// code
}- Building off #3 under the General Style, it's easier to see what's going on if you add more information to a function's signature. If a function modifies two member variables, it's good to see which variables are being modified in the function signature.
Bad:
public class FancyClass
{
private int _x;
private int _y;
/* ... */
public int Calculate()
{
// code to calculate _x and _y
}
}Good:
public class FancyClass
{
private int _x;
private int _y;
/* ... */
public int Calculate(in int x, in int y)
{
// code to calculate x and y
}
}Both of these functions above do the same thing, but the second one is arguably more explicit. If the first Calculate is called, it is called like this: Calculate(). But if it's called in the second example, Calculate(in _x, in _y), you can clearly see what is being calculated: _x and _y. By explictly passing _x and _y to Caclate, there is no need to hunt down the function to see what it's calculating -- we know what's being calcuatled in virtue of the arguments that are passed to it.
By also having the in annotation, you can see that both _x and _y are not being modifed -- they're only being used as a readonly reference in the function.
- Use lower case tag name
Bad:
<DIV>
<P>YEAH</P>
</DIV>Good:
<div>
<p>YEAH</p>
</div>
- Close every tag
Bad:
<div>
<p>YEAH
<img src="~/my/picture/link.jpg" >
</div>Good:
<div>
<p>YEAH</p>
<img src="~/my/picture/link.jpg" />
</div>
- Use lower case attributes
Bad:
<div CLASS="my-class">
<p>YEAH</p>
</div>Good:
<div class="my-class">
<p>YEAH</p>
</div>
- CSS rules should be listed alphabetically
Bad:
#my_id {
width: 100%;
color: red;
max-width: 500px;
background-color: black;
}Good:
#my_id {
background-color: black;
color: red;
max-width: 500px;
width: 100%;
}
- Classes and Ids should also be written in lower cases
- Classes should be written with hypens for spacing, and ids should be written with underscores for spacing
Bad:
#my-ID {
background-color: black;
}
.my__class {
color: red;
}Good:
#my_id {
background-color: black;
}
.my-class {
color: red;
}