The Generic Rules
In this lesson, we will go through some of the generic rules we should follow in C#.
C# is a general-purpose, strongly typed, object-oriented programming language. Let’s quickly go through some of the generic rules one should follow while coding in C#.
The Do’s and Don’ts
- Do use PascalCasing for class names and method names:
public class ClientActivity{public void ClearStatistics(){//...}public void CalculateStatistics(){//...}}
Why: consistent with the Microsoft’s .NET Framework and easy to read.
- Do use camelCasing for method arguments and local variables:
public class UserLog{public void Add(LogEvent logEvent){int itemCount = logEvent.Items.Count;// ...}}
Why: consistent with the Microsoft’s .NET Framework and easy to read.
- Do not use Hungarian notation or any other type identification in identifiers
// Correctint counter;string name;// Avoidint iCounter;string strName;
Why: consistent with the Microsoft’s .NET Framework. In general you want to avoid type indicators in any identifier.
- Do not use Screaming Caps for constants or readonly variables:
// Correctpublic const string ShippingType = "DropShip";// Avoidpublic const string SHIPPINGTYPE = "DropShip";
Why: consistent with the Microsoft’s .NET Framework. Caps grab too much attention.
- Do use meaningful names for variables. The following example uses seattleCustomers for customers who are located in Seattle:
var seattleCustomers = from customer in customerswhere customer.City == "Seattle"select customer.Name;
Why: consistent with the Microsoft’s .NET Framework and easy to read.
- Avoid using Abbreviations. Exceptions: abbreviations commonly used as names, such as Id, Xml, Ftp, Uri.
// CorrectUserGroup userGroup;Assignment employeeAssignment;// AvoidUserGroup usrGrp;Assignment empAssignment;// ExceptionsCustomerId customerId;XmlDocument xmlDocument;FtpHelper ftpHelper;UriPart uriPart;
Why: consistent with the Microsoft’s .NET Framework and prevents inconsistent abbreviations.
- Do use PascalCasing for abbreviations 3 characters or more (2 chars are both uppercase):
HtmlHelper htmlHelper;FtpTransfer ftpTransfer;UIControl uiControl;
Why: consistent with the Microsoft’s .NET Framework. Caps would grab visually too much attention.
- Do not use Underscores in identifiers. Exception: you can prefix private fields with an underscore:
// Correctpublic DateTime clientAppointment;public TimeSpan timeLeft;// Avoidpublic DateTime client_Appointment;public TimeSpan time_Left;// Exception (Class field)private DateTime _registrationDate;
Why: consistent with the Microsoft’s .NET Framework and makes code more natural to read (without ‘slur’). Also avoids underline stress (inability to see underline).
- Do use predefined type names (C# aliases) like
int
,float
,string
for local, parameter and member declarations. Do use .NET Framework names like Int32, Single, String when accessing the type’s static members likeInt32.TryParse
orString.Join
.
// Correctstring firstName;int lastIndex;bool isSaved;string commaSeparatedNames = String.Join(", ", names);int index = Int32.Parse(input);// AvoidString firstName;Int32 lastIndex;Boolean isSaved;string commaSeparatedNames = string.Join(", ", names);int index = int.Parse(input);
Why: consistent with the Microsoft’s .NET Framework and makes code more natural to read.
- Do use implicit type
var
for local variable declarations. Exception: primitive types (int
,string
,double
, etc) use predefined names.
var stream = File.Create(path);var customers = new Dictionary();// Exceptionsint index = 100;string timeSheet;bool isCompleted;
Why: removes clutter, particularly with complex generic types.
- Do use noun or noun phrases to name a class.
public class Employee{}public class BusinessLocation{}public class DocumentCollection{}
Why: consistent with the Microsoft’s .NET Framework and easy to remember.
- Do prefix interfaces with the letter
I
. Interface names are noun (phrases) or adjectives.
public interface IShape{}public interface IShapeCollection{}public interface IGroupable{}
Why: consistent with the Microsoft’s .NET Framework.
- Do name source files according to their main classes. Exception: file names with partial classes reflect their source or purpose, e.g. designer, generated, etc.
// Located in Task.cspublic partial class Task{}// Located in Task.generated.cspublic partial class Task{}
Why: consistent with the Microsoft practices. Files are alphabetically sorted and partial classes remain adjacent.
- Do organize namespaces with a clearly defined structure:
// Examplesnamespace Company.Product.Module.SubModule{}namespace Product.Module.Component{}namespace Product.Layer.Module.Group{}
Why: consistent with the Microsoft’s .NET Framework. Maintains good organization of your code base.
- Do vertically align curly brackets:
// Correctclass Program{static void Main(string[] args){//...}}
Why: Microsoft has a different standard, but developers have overwhelmingly preferred vertically aligned brackets.
- Do declare all member variables at the top of a class, with static variables at the very top.
// Correctpublic class Account{public static string BankName;public static decimal Reserves;public string Number { get; set; }public DateTime DateOpened { get; set; }public DateTime DateClosed { get; set; }public decimal Balance { get; set; }// Constructorpublic Account(){// ...}}
Why: generally accepted practice that prevents the need to hunt for variable declarations.
- Do use singular names for enums. Exception: bit field enums.
// Correctpublic enum Color{Red,Green,Blue,Yellow,Magenta,Cyan}// Exception[Flags]public enum Dockings{None = 0,Top = 1,Right = 2,Bottom = 4,Left = 8}
Why: consistent with the Microsoft’s .NET Framework and makes the code more natural to read. Plural flags because enum can hold multiple values (using bitwise ‘OR’).
- Do not explicitly specify a type of an enum or values of enums (except bit fields):
// Don'tpublic enum Direction : long{North = 1,East = 2,South = 3,West = 4}// Correctpublic enum Direction{North,East,South,West}
Why: can create confusion when relying on actual types and values.
- Do not use an “Enum” suffix in enum type names:
// Don'tpublic enum CoinEnum{Penny,Nickel,Dime,Quarter,Dollar}// Correctpublic enum Coin{Penny,Nickel,Dime,Quarter,Dollar}
Why: consistent with the Microsoft’s .NET Framework and consistent with prior rule of no type indicators in identifiers.
- Do not use “Flag” or “Flags” suffixes in enum type names:
// Don't[Flags]public enum DockingsFlags{None = 0,Top = 1,Right = 2,Bottom = 4,Left = 8}// Correct[Flags]public enum Dockings{None = 0,Top = 1,Right = 2,Bottom = 4,Left = 8}
Why: consistent with the Microsoft’s .NET Framework and consistent with prior rule of no type indicators in identifiers.
- Do use suffix EventArgs at creation of the new classes comprising the information on event:
// Correctpublic class BarcodeReadEventArgs : System.EventArgs{}
Why: consistent with the Microsoft’s .NET Framework and easy to read.
- Do name event handlers (delegates used as types of events) with the “EventHandler” suffix, as shown in the following example:
public delegate void ReadBarcodeEventHandler(object sender, ReadBarcodeEventArgs e);
Why: consistent with the Microsoft’s .NET Framework and easy to read.
- Do not create names of parameters in methods (or constructors) which differ only by the register:
// Avoidprivate void MyFunction(string name, string Name){//...}
Why: consistent with the Microsoft’s .NET Framework and easy to read, and also excludes possibility of occurrence of conflict situations.
- DO use two parameters named sender and e in event handlers. The sender parameter represents the object that raised the event. The sender parameter is typically of type object, even if it is possible to employ a more specific type.
public void ReadBarcodeEventHandler(object sender, ReadBarcodeEventArgs e){//...}
Why: consistent with the Microsoft’s .NET Framework