Coding Standard and Guidelines

From OpenPetra Wiki
Revision as of 13:06, 14 July 2010 by Pokorra (talk | contribs) (Created page with '=About the C# Coding Style Guide= '''This document may be read as a guide to writing robust and reliable C# programs.''' Notes: # Many of the rules in this document can be ''a…')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

About the C# Coding Style Guide

This document may be read as a guide to writing robust and reliable C# programs.

Notes:

  1. Many of the rules in this document can be applied automatically to source code using the 'Uncrustify' tool that we use (make uncrustify)
    1. Those rules are marked with 'Enforced by Uncrustify.'
  2. Many of the rules in this document can be checked automatically with the 'StyleCop' tool that we use (make stylecop)!
    1. Those rules are marked with 'Checked by StyleCop.' TODO
  3. 'Uncrustify' and 'StyleCop' and how we use them with Petra are described in Coding Standards Tools: 'Uncrustify' and 'StyleCop'.

This 'C# Coding Style Guide' was inspired by the [C# Coding Style Guide], written by Mike Krüger, [[1]]. This is used by the sharpDevelop programmers who work on the SharpDevelop IDE.


File Organization

C# Sourcefiles

  • Keep your classes/files short: try hard not to exceed 3.000 lines of code, never go beyond 4.000 lines of code.
    • Exception to that
      • Auto-generated code can ignore that rule if the generated file doesn't need to be looked at/touched by developers.
  • Divide your code up, make structures clearer.
  • Every class should go in a separate file.
    • Exceptions to that
      • Helper classes for the main class in the same file are allowed. Those helper classes must be private classes, though!
      • Auto-generated code can ignore that rule if the generated file doesn't need to be looked at/touched by developers.
  • The file name should reflect the name of the class in the file (.cs as extension of course).
    • Exception to that
      • The file name of a source file can have the last part of a Namespace in it if the Namespace is nested quite deeply and

the directory structure doesn't reflect that deep nesting anymore (see 'Directory Layout' below). Example: DataAggregates.PPartnerAddress.cs in Namespace 'Ict.Petra.Server.MPartner.DataAggregates' in directory 'U:\delphi.net\ICT\Petra\Server\lib\MPartner'.


These conventions makes things much easier to read and find.


Directory Layout

  • Create a directory for every namespace. Example: for Namespace 'Ict.Petra.Server.App.Core' use 'U:\delphi.net\ICT\Petra\Server\app\' as the path (do not use the Namespace name with dots for directory names).
    • Exceptions to that
      • Additional directories might be placed inbetween parts of the Namespace if that benefits the directory structure and a agreed rule when to do that is followed. Example: Namespace 'Ict.Petra.Server.MPartner.DataAggregates' resides in directory 'U:\delphi.net\ICT\Petra\Server\lib\MPartner'. Note the 'lib' directory, which is inserted.
      • If a Namespace is nested quite deeply, we can opt to have the directory structure not reflecting that deep nesting. In that case, the last part of a Namespace should then be part of the file name of a Class (see 'C# Sourcefiles' above).


These conventions make it easier to map namespaces to the directory layout.


Indentation

White Spaces

For code indentation, two standards exist in the world of programming: indendation with spaces and indendation with tabs. Some programmers prefer spaces, others prefer tabs.

Here, we define the space character as the standard indentation character. Specifically, we indent everything with four spaces - Enforced by Uncrustify. This applies for the indendation from column 1 to the indendation level of the current code and also to any further indendations from there.

By using spaces, not tabs, we can ensure that our code is indented identically for every developer and in every editor. Would we use tabs, the indentation could vary.

Don't use tabs for indentation - use spaces! Enforced by Uncrustify.

Wrapping Lines

When an expression will not fit on a single line, break it up before it reaches more than 150 characters. Enforced by Uncrustify. You might want to break it up before that for readability.

Follow these general principles when breaking up a line:

  • Break after a comma.
  • Break after an operator.
  • Prefer higher-level breaks to lower-level breaks.
  • Indent the new line at the standard indentation level, or align the new line with the beginning of the expression at the same level on the previous line.

Example of breaking up method calls: <codepre> LongMethodCall(expr1, expr2,

    expr3, expr4, expr5);  // indented at the standard indentation level

</codepre>

or

<codepre> LongMethodCall(expr1, expr2,

               expr3, expr4, expr5);  // aligned with the beginning of the expression on the previous line

</codepre>

The first is preferred because it results in uniformly formatted code, but if indenting with the second method makes for better reading in a specific case then use the second method.


Examples of breaking an arithmetic expression:

PREFER:

<codepre> var = a * b / (c - g + f) +

   4 * z;

</codepre>

BAD STYLE – AVOID: <codepre> var = a * b / (c - g +

   f) + 4 * z;

</codepre>

The first is preferred, since the break occurs outside the paranthesized expression (higher level rule).


Comments

All comments must be written in English.

Block Comments

Block comments for the purpose of describing Classes, Methods, etc. should be avoided. Instead, use of the /// comments to give C# standard descriptions is recommended (see 'Documentation Comments' below).

If you wish to use block comments inside Methods, Classes, etc. you should use the following style:

<codepre> /* The following Algorithm does bla bla bla

* and is adapted from the well-known blah blah Algorithm.

* An example of this Algorithm can be found on http://www.blahalgorithms.org

*/ </codepre>

...as this will set off the block visually from code for the (human) reader.

Block comments may be useful in rare cases, refer to the TechNote ['The fine Art of Commenting'] for an example.

A rule of thumb says that generally, the length of a comment should not exceed the length of the code explained by too much, as this is an indication of too complicated, potentially buggy, code.

For commenting out sections of code, use the 'Single Line Comments' (despite their name) to distinguish better between code comments and commented out code.

Single Line Comments

You should use the // (two forward slahes) comment style to "comment out" code (SharpDevelop has a shotcut key for it, Alt+/). It may be used for commenting out sections of code too.

Note on using StyleCop: because we will use StyleCop, rather use //// (four forward slashes) instead of // when commenting out single lines of code. This helps the tool to not confuse it with a single line comment (which is not commented out code). (Refers to StyleCop Rule SA1512: SingleLineCommentsMustNotBeFollowedByBlankLine.)


Single line code comments must be indented to the indent level when they are used for code documentation. Commented out code should be commented out so that the // (two slashes) start in column 1. This is to enhance the visibility of commented out code.

Documentation Comments

In the .NET framework, Microsoft has introduced a documentation generation system based on XML comments. These comments are formally single line C# comments containing XML tags. They follow this pattern for single line comments:

<codepre> /// <summary>

/// This class...

/// </summary> </codepre>

Multiline XML comments follow this pattern:

<codepre> /// <exception cref=”BogusException”>

/// This exception gets thrown as soon as a

/// Bogus flag gets set.

/// </exception> </codepre>

All lines must be preceded by /// (three slashes) to be accepted as XML comment lines.

Tags fall into two categories:

  • Documentation items
  • Formatting/Referencing

The first category contains tags like <summary>, <param> or <exception>. These represent items that represent the elements of a program's API which must be documented for the program to be useful to other programmers. These tags usually have attributes such as name or cref as demonstrated in the multi line example above. These attributes are checked by the compiler, so they should be valid.

The latter category governs the layout of the documentation, using tags such as <code>, <list> or <para>.

For a fuller explanation of XML comments see [CSharp In-Code Documentation with MS XML Tags]. For information on how to produce API-style documentation for C# Projects whose .cs files contain XML Comment Tags see [How to produce CSharp API Documentation].

For information on commenting best practice and further issues related to commenting, see the TechNote ['The fine Art of Commenting'].

End Comments

By 'End Comments' we mean adding a single-line comment after the closing curly brace "}" of a code block to explain what section of code the closing curly braces ends.

We decided this is unnecessary if this information is obvious. In other words, use 'End Comments' only when the meaning of the closing curly brace "}" of a code block is not immediately obvious due to either a very long block, or in the case of many nested blocks.

Modification Logs

We decided to depend on the History and Commit comments of CVS for modification logs rather than creating our own in the code.

Insert the following at the very end of each .cs file unit (after the last closing curly brace "}"):

<codepre>

}


/* CVS HISTORY $Log$ */ </codepre>


For this to work however, we need to be diligent with our commit comments, and commit as often as possible.


Declarations

Number of Declarations per Line

Only one declaration per line is allowed. This greatly enhances readabiliy and it encourages commenting.

GOOD STYLE:

<codepre> int Level; // indentation level int Size; // size of table </codepre>

Do not put more than one variable or variables of different types on the same line when declaring them.

BAD STYLE - AVOID:

<codepre> int Var1, Var2; // What is 'Var1'? What does 'Var2' stand for? </codepre>

Declarations should be followed by an empty line so that they are visually set apart from the rest of the source code. Enforced by Uncrustify.

The above example also demonstrates the drawbacks of non-obvious variable names.

Be clear when naming variables. Using self-explanatory variable names such as IndentLevel make above comments obsolete.

Initialization

Try to initialize local variables as soon as they are declared.

For example:

<codepre> string Name = myObject.Name; int Val = time.Hours; </codepre>

Initialisations should be followed by an empty line so that they are visually set apart from the rest of the source code. Enforced by Uncrustify if the initialisations are part of declarations.

Note: When initializing a Dialog/Modal Form (by using .ShowDialog instead of .Show), use the following construct to be sure the Form is released from memory when it is closed:

<codepre> using (TOpenFileDialog openFileDialog = new TOpenFileDialog()) {

  openFileDialog.ShowDialog();
   ...

} // .NET will release openFileDialog automatically, so we can't forget about it! </codepre>

Background: Forms shown with .ShowDialog are not released from memory, but kept in memory so the caller can call methods after the Form is closed to retrieve parameters. Therefore one can forget to release the form from memory later.

Class, Interface and Namespace Declarations

For C# classes, interfaces and namespaces, the following formatting rules should be followed:

  • Braces
    • The opening brace "{" appears in the next line after the declaration statement.
    • The closing brace "}" starts a line by itself indented to match its corresponding opening brace.
    • The opening brace "{" and the closing brace "}" should be on the same indentation level as the code block construct that owns it.
  • Spacing
    • A single space character should be placed on each side of the colon that follows the class name.
    • If there is a list of types/interfaces that the class inherits from, the items should be separated by a comma followed by a space character.
  • Code block separation
    • An empty line should preceed and succeed each class, interface or namespace block.
      • Exceptions
        • if a class, interface or namespace block begins immediately after another class, interface or namespace block has been started with an opening brace "{": no empty line.
        • if a class, interface or namespace block ends and another enclosing code block also ends immediately after the closing brace "}": no empty line.

For example:

<codepre> namespace MyNamespace { // no empty line

   class TMySample : TMyClass, IMyInterface
   {
       void DoSomething()
       {
       
       }
       
       void DoAnotherThing()
       {
       
       }
   }
                                                      // empty line goes here
   class TMyOtherSample : TMySample, IMyOtherInterface
   {
       void DoSomething()
       {
       
       }
       
       void DoAnotherThing()
       {
       
       }
   }                                                  // no empty line

} </codepre>

For another brace placement example look at section 'Code Examples - Brace placement example'.

Enforced by Uncrustify: all rules

Method Declarations

For method declarations the following formatting rules should be followed:

  • Braces
    • Class braces placement rules should be applied.
  • Spacing
    • No space should be put between a method name and the opening parenthesis "(" that starts its parameter list.
  • Code block separation
    • An empty line should preceed and succeed the statement block (the same applies to other statements that appear as blocks of code).

For example:

<codepre>

                                                      // empty line goes here

public MySample(int AMyInt) {

   this.FMyInt = AMyInt;

}

                                                      // empty line goes here

void Inc() {

   ++FMyInt;

}

                                                      // empty line goes here

</codepre>

Enforced by Uncrustify: all rules

Property, Indexer and Event Declarations

For properties, indexers and events, the following formatting rules should be followed:

  • Braces
    • Class braces placement rules should be applied. Enforced by Uncrustify: all rules, except for 'opening curly bracket must be on new line' (Uncrustify can't enforce that for EventHandlers).
  • Spacing
    • For properties where both 'get' and 'set' blocks are present, an empty line should be placed between the 'get' block and the 'set' block.
    • For event handlers where both 'add' and 'remove' blocks are present, an empty line should be placed between the 'add' block and the 'remove' block.
    • For indexers, use no space between 'this' and '['. Enforced by Uncrustify.
  • Code block separation
    • An empty line should preceed and succeed the statement block (the same applies to other statements that appear as blocks of code).
  • No one-liners
    • Always use braces "{" and "}" on their own code lines even if there is only one statement in the getter/setter or adder/remover!

For example: <codepre>

                                                      // empty line goes here

public int Amount {

   get 
   {
       ...
   }
                                                      // empty line goes here    
   set 
   {
       ...
   }

}

                                                      // empty line goes here

public EventHandler MyCustomEventHandler {

   add 
   {
       ...
   }
                                                      // empty line goes here
   remove 
   {
       ...
   }

}

                                                      // empty line goes here

public this[string index] {

   get;
                                                      // empty line goes here    
   set;

}

                                                      // empty line goes here

</codepre>

Simple Statements

Each code line should contain only one statement.

Return Statements

A return statement should not use outermost parentheses. Enforced by Uncrustify.

GOOD STYLE :

return (n * (n + 1)) / 2;

BAD STYLE - AVOID:

return ((n * (n + 1)) / 2);


Statements With Multiple Conditions

In a situation where more than one condition is specified (eg. in if, for or do-while-statments), please follow these guidelines:

  • Place each condition on a separate line.
  • Place the && and || that connects the conditions on the same line as the next condition. (see example)
  • If you have a very complicated condition statement, try to align the different conditions. The goal is to make the condition more readable in the end, so you may use you discretion here as well.

Example: <codepre> if (((condition1)

    && (condition2)
    || (condition3
        && condition4))
   (&& !condition5))

{

  ...

} </codepre>

If, if-else, if else-if else Statements

if, if-else and if else-if else statements should follow the following formatting rules:

  • Braces
    • Class braces placement rules should be applied.
  • Spacing
    • A space character should be put between "if" and the opening parenthesis "(".
    • No space character should be put between the opening bracket "(" and the following code, no space character between code and the closing bracket ")".
  • Code block separation
    • An empty line should preceed and succeed the statement block (the same applies to other statements that appear as blocks of code).
  • No one-liners
    • Always use braces "{" and "}" on their own code lines even if there is only one statement in the condition!

For example: <codepre>

                       // empty line goes here

if (condition) {

   DoSomething();
   ...

}

                       // empty line goes here

if (condition) {

   DoSomething();
   ...

} else {

   DoSomethingOther();
   ...

}

                       // empty line goes here

if (condition) {

   DoSomething();
   ...

} else if (condition) {

   DoSomethingOther();
   ...

} else {

   DoSomethingOtherAgain();
   ...

}

                       // empty line goes here

</codepre>

Enforced by Uncrustify: all rules

6.4 For / Foreach Statements

For and foreach statements should follow the following formatting rules:

  • Braces
    • Class braces placement rules should be applied.
  • Spacing
    • A space character should be put between "for"/"foreach" and the opening parenthesis "(".
    • No space character should be put between the opening bracket "(" and the following code, no space character between code and the closing bracket ")".
    • for only
      • Space characters should be put after the semicolon ";" which separates the initialisation, condition and execution code parts (contained inside the brackets).
      • Inter-term spacing rules should be applied (see 'Inter-term spacing' below).
  • Code block separation
    • An empty line should preceed and succeed the statement block (the same applies to other statements that appear as blocks of code).
  • No one-liners
    • Always use braces "{" and "}" on their own code lines even if there is only one statement in the loop!


For example: <codepre>

                                                      // empty line goes here

for (int Counter = 0; Counter < 5; ++Counter) {

   ...

}

                                                      // empty line goes here

foreach (int MyIterator in IntList) {

   ...

}

                                                      // empty line goes here

</codepre>

Enforced by Uncrustify: all rules

6.5 While/do-while Statements

while/do statements should follow the following formatting rules:

  • Braces
    • Class braces placement rules should be applied.
  • Spacing
    • A space character should be put between "while" and the opening parenthesis "(".
    • No space character should be put between the opening bracket "(" and the condition, no space character between the condition and the closing bracket ")".
  • Code block separation
    • An empty line should preceed and succeed the statement block (the same applies to other statements that appear as blocks of code).
  • No one-liners
    • Always use braces "{" and "}" on their own code lines even if there is only one statement in the loop!

For example: <codepre>

                                                      // empty line goes here

while (condition) {

   ...

}

                                                      // empty line goes here

</codepre>

An empty while should have the following form:

<codepre> while (condition) {

   ;

} </codepre>

A do-while statement should have the following form:

<codepre>

                                                      // empty line goes here

do {

   ...

} while (condition);

                                                      // empty line goes here

</codepre>

Enforced by Uncrustify: all rules

6.6 Switch Statements

A switch statement should follow the following formatting rules:

  • Braces
    • Class braces placement rules should be applied.
  • Spacing
    • A space character should be put between "switch" and the opening parenthesis "(".
    • No space character should be put between the opening bracket "(" and the condition, no space character between the condition and the closing bracket ")".
  • Code block separation
    • An empty line should preceed and succeed the statement block (the same applies to other statements that appear as blocks of code).
    • An empty line should succeed each 'break;' statement.
      • Exception: no empty line after the 'break;' statement in the 'default' block.
  • Other line breaks
    • the case x: condition and the following statement(s) as well as the default: line and the following statement(s) should be separated by a line break.

For example: <codepre>

                                                      // empty line goes here

switch (condition) {

   case A:                                            // line break here
       ...
       break;
                                                      // empty line goes here
   case B:                                            // line break here
       ...
       break;
                                                      // empty line goes here
   default:                                           // line break here
       ...
       break;                                         // NO empty line to follow!

}

                                                      // empty line goes here

</codepre>

Enforced by Uncrustify: all rules

6.7 Try-catch Statements

try-catch statements should follow the following formatting rules:

  • Braces
    • Class braces placement rules should be applied.
  • Code block separation
    • An empty line should preceed and succeed the statement block (the same applies to other statements that appear as blocks of code).
  • No one-liners
    • Always use braces "{" and "}" on their own code lines even if there is only one statement in the respective try/except/finally section!

For example: <codepre>

                                                      // empty line goes here

try {

   ...

} catch (Exception) {

   ...

}

                                                      // empty line goes here

</codepre>

or

<codepre>

                                                      // empty line goes here

try {

   ...

} catch (ApplicationException ae) {

   ...

} catch (Exception e) {

   ...

} finally {

   ...

}

                                                      // empty line goes here

</codepre>

Enforced by Uncrustify: all rules, except for

  • 'Code block separation' (Uncrustify can't enforce that);
  • 'Opening curly bracket must be on new line' for the 'finally' statement (Uncrustify's rule to enforce that doesn't work).

White Space

Blank Lines

Blank lines improve readability by setting off blocks of code which are in themselves logically related.

Two blank lines should always be used between:

  • Logical sections of a source file.
  • Class and interface definitions (try one class/interface per file to prevent this case).

One blank line should always be used between:

  • Methods. Enforced by Uncrustify
  • Properties.
  • Code blocks (if statements, for/foreach loops and while loops, switch blocks and try/catch blocks). Enforced by Uncrustify
  • Local variables in a method and the first statement in the method. Enforced by Uncrustify (although not always reliable)
  • Logical sections inside a method to improve readability.

Blank lines should be indented to the correct indent level instead of leaving them blank or more worse using another indentation level. This makes the insertion of new statements in these lines much easier.

Inter-term spacing

There should be a single space after a comma or a semicolon.

For example: <codepre> TestMethod(a, b, c); // don't use : TestMethod(a,b,c) </codepre>

Single spaces surround operators (except unary operators like increment (++) or logical not (!)).

For example: <codepre> a = b; // don't use a=b;

for (int Counter = 0; Counter < 10; ++Counter) // don't use 'for (int i=0; i<10; ++i)'

                                                  // or 'for(int i=0;i<10;++i)'

</codepre>

Enforced by Uncrustify: all rules


Naming Conventions

All names of all code elements must be written in English.

Capitalization Styles

Pascal Casing

This convention capitalises the first character of each word (as in TestCounter).

Camel Casing

This convention capitalises the first character of each word except the first word (as in testCounter).

All-Uppercase

All-uppercase capitalises all characters of a word. Use all-uppercase only for constant identifiers. (For non-constant identifiers that are commonly used in all-uppercase (eg. URL, PI) use PascalCasing instead.)


Naming Guidelines

Naming according to the guidelines for 'Hungarian Notation' is considered bad practice.

Hungarian Notation is a defined set of prefixes and postfixes which are applied to names to reflect the type of the variable. This style of naming was widely used in early Windows programming, but is now obsolete or at least should be considered deprecated. Using Hungarian Notation is not allowed if you follow this guide.

And remember: a good variable name describes the semantic not the type.

An exception to this rule is GUI code. All fields and variable names that contain GUI elements like Button should be prefixed with their respective GUI control prefix.

For example: <codepre> System.Windows.Forms.Button btnCancel; System.Windows.Forms.TextBox txtName; </codepre>

Namespace Naming Guidelines

  • Namespace names should be nouns or noun phrases.
  • Use PascalCasing.
  • Name prefix: none.

Class Naming Guidelines

  • Class names should be nouns or noun phrases.
  • Use PascalCasing.
  • Name prefix: 'T' (stands for Type). It is to be followed by a capital letter (first character of the class name).
    • Classes that are derived from System.Windows.Form should use the prefix TFrm instead.

For example: <codepre> public class TConnection {

   ...

}


public class TFrmAboutPetra {

   ...

} </codepre>

Interface Naming Guidelines

  • Name interfaces with nouns or noun phrases or adjectives describing behavior.
  • Use PascalCasing
  • Name prefix: 'I' (stands for Interface). It is to be followed by a capital letter (first character of the interface name).

For example: <codepre> public interface IComponent {

   ...

} </codepre>

Exception Naming Guidelines

  • Name Exceptions with nouns or noun phrases.
  • Use PascalCasing
  • Name prefix: 'E' (stands for Exception). It is to be followed by a capital letter (first character of the exception name). Exceptions should also include the word Exception as a suffix to the name.

For example: <codepre> public class EConnectionException {

   ...

} </codepre>

Enum Naming Guidelines

  • Name
    • Use singular names for enum types. PascalCasing.
    • Use singular names for enum values. camelCasing.
  • Prefixes
    • Enum type name: 'T'. It is to be followed by a capital letter (first character of the enum name). Enum types should also include the word Enum as a suffix to the name.
    • Enum values: concatenate the letters of each word that make up the enum type name and prefix those in lower case to the enum value.


For example: <codepre> public enum TModuleSwitchEnum {

   msNone, msPartner, msPersonnel, msFinance

}


public enum TUIConnectorTypeEnum {

   uictPartnerKey, uictLocationKey, uictNewPartner

} </codepre>

Event Names

Event Handlers:

  • Name event handlers with the EventHandler suffix.
  • Name event handlers that have a concept of pre and post using the present and past tense (eg. ...ChangingEventHandler and ...ChangedEventHandler).
  • For generic event handlers use two parameters named sender and e.
  • Use PascalCasing.
  • Prefix: 'T'. It is to be followed by a capital letter (first character of the event handler).

Event Arguments:

  • Name event argument classes with the EventArgs suffix.
  • Consider naming events using a verb.
  • Use PascalCasing.
  • Prefix: 'T'. It is to be followed by a capital letter (first character of the event argument class).

Property Names

  • Name properties using nouns or noun phrases.
  • Consider naming a property with the same name as it’s Type.
  • Use PascalCasing.
  • Prefix: None!

Method Names

  • Name methods with verbs or verb phrases.
  • Use PascalCasing.
  • Prefix: None!

Argument Names

'Arguments' are arguments that are passed to a method. They are used much like private variables of a method.

  • Use descriptive names, which should be enough to determine the argument's meaning and it’s type. But prefer a name that’s based on the argument’s meaning.
  • Use PascalCasing.
  • Prefix: 'A' (stands for Argument). It is to be followed by a capital letter (first character of the argument name).

Field Names

'Fields' are private variables of a class.

  • Use descriptive names, which should be enough to determine the field's meaning and it’s type. But prefer a name that’s based on the field's meaning.
  • Use PascalCasing.
  • Prefix: 'F' (stands for Field). It is to be followed by a capital letter (first character of the field name).

Variable Names

'Variables' are private variables of a method.

  • Use descriptive names, which should be enough to determine the variable's meaning and it’s type. But prefer a name that’s based on the variable’s meaning.
  • Boolean Variables: Prefer using prefixes like 'Is...', 'Has...' or 'Can...'. Generally you should give boolean variables names that imply true or false (eg. 'FileFound', 'Done', 'Success') or with its prefixes: 'IsFileFound', 'IsDone', 'IsSuccess' - but don't try 'IsName' that doesn't make sense at all.
  • Loop counters: These are variables used in loops to serve as counters, indexes, or the like. You should use Counter as the standard name for these kinds of variables. Whenever you have a nested loop that also uses a counter, add numbers to the end to indicate the level of the counter.
  • Temporary Variables: Many times you need to use a variables with no specific meaning - just a quick place-holder or something that will have but a moment of usage. These variables should be called Tmp. Whenever you need to have more than one temporary variable, it warrants some more thinking on the part of the programmer to find better names for these variables.
  • Use PascalCasing.
  • Prefix: None!

Const Names

  • Name constant fields with nouns, noun phrases or abbreviations for nouns. If they consist of more than one word, separate the words with underscore characters (_).
  • Use ALL-UPPERCASE
  • Prefix: None!

For example: <codepre> public class TMath {

   public const string LONG_CONST_NAME = ...
   public const double PI = 3.14...
   public double Pi = 3.14...                         // this is a variable and not a constant, 
                                                      // so don't use PI

} </codepre>

Naming and Capitalisation summary

Type

Prefix

Case

Notes

Namespaces

none

Pascal Casing

Classes / Structs

T

Pascal Casing

Special prefix: TFrm if derived from System.Windows.Form.

Interfaces I

Pascal Casing

Exception Classes

E

Pascal Casing

Suffix: Exception.

Enum Types

T

Pascal Casing

Suffix: Enum

Enum Values

see Notes

Camel Casing

Prefix: Concatenate the letters of each word that make up the enum type name and prefix those in lower case to the enum value.

Event Handlers / Event Arguments

T

Pascal Casing

Suffix for Event Handlers: EventHandler. Suffix for Event Arguments: EventArgs.

Properties

none

Pascal Casing

Methods

none

Pascal Casing

Arguments

A

Pascal Casing

Fields

F

Pascal Casing

Local variables

none

Pascal Casing

Global Variables

G

Pascal Casing

Constants

none

All-Uppercase


Programming Practices

Visibility

Generally

Give a class, interface, event handler, method, field always the least possible visibility. This means that you should consider giving it private visibility, and only if that is not enough increase the visibility - but only as much as is needed.

Fields

Do not make fields public - always make them private. Create properties for fields instead. You may use public static fields (or consts) as an exception to this rule, but be very careful with it.

Having appropriate visibility ensures proper use of classes by every programmer and is kind of 'self-documenting' in the way that it tells how the class can be used.

No 'Magic' Numbers

Do not use 'magic' numbers, i.e. place constant numerical values directly into the source code. Replacing these lateron in case of changes (say, your application can now handle 3540 users instead of the 427 users hardcoded into your code in 50 lines scattered troughout your 25000 lines of code) is error-prone and unproductive. Instead declare a const which contains the number:

<codepre> public class TMyMath {

   public const double PI = 3.14... 

} </codepre>

SQL Queries

All SQL keywords should be in capital letters.

The main query command keyword (e.g. SELECT, UPDATE, INSERT, etc.) should be on the indentation base, and the rest of the text belonging to that query should be indented.

Indentation for SQL queries should be four spaces (like for the rest of the source code).

If the list of columns or tables become to long, it should be split over more than one line. If this is done, the lists should be aligned.

Every keyword that signifies a new 'section' of the query should be on a new line, with everything belonging to that section indented. (See example.)

The keywords AND and OR should also be on a new line, and indented. It is also recommended to try and align the conditions. To do this, simply add a few spaces after the AND and OR keywords until the condition is aligned to the one in the previous line.


Cumulative examples:

<codepre>

 SELECT a_column_1_i, a_column_2_l,
        a_column_3_i, a_column_4_n
   FROM  a_table
   WHERE a_column_1_i > 5
     AND a_column_2_l = TRUE
     OR  a_column_4_n = 10
   ORDER BY a_column_3_i;



 SELECT surname, forenames
   FROM  employee
   WHERE depno =
         (SELECT depno
           FROM  employee
           WHERE empno = 16)
     AND empno != 16



 DELETE FROM a_whatever
   WHERE mmm
     AND mmm
     OR  mmm



 UPDATE a_whatever
   SET (mm1 = 'khasg kvjshdfbv jszhdvb kszjhvb ksjvhb asj,f abv,jfhv badfj',
        mm2 = (SELECT id
                 FROM  something
                 WHERE something else)
        mm3, mm4)
   WHERE mmm
     AND mmm;

</codepre>


Table aliases can be named by using the first letter of every word in the table name (excluding unnecessary things like prefixes). If the same table is used twice in the query with two aliases, simply add a number at the end of the alias name to distinguish them, or name them in such a way as to separate them logically.

Never use SELECT * for a query in Petra! This can cause a lot of data transfer! By not using it you can prevent errors, and also make life much easier for things like typeddatasets.

Use Discretion!

These standards were set up to help us as programmers to better maintain the code. Please try to comply to these standards.

We realise that there are times when the standards would actually have a negative effect, or maybe where the standards are not entirely clear. In these situations, please use your discretion to come up with a suitable alternative, and discuss it with the rest of the team before you use it.


Code Examples

Brace placement example

<codepre> namespace ShowMeTheBracket {

   public enum TTheTestEnum
   {
       ttOne, ttTwo
   }


   public class TTestMeClass
   {
       TTheTestEnum FTestVar;


       public TTheTestEnum Test 
       {
           get 
           {
               return FTestVar;
           }
           
           set 
           {
               FTestVar = value;
           }
       }


       void DoSomething()
       {
           if (FTestVar == TTestEnum.ttOne) 
           {
               //...stuff gets done
           } 
           else 
           {
               //...other stuff gets done
           }
       }
   }

} </codepre>

Variable naming example

Instead of:

<codepre> for (int i = 1; i < num; ++i) {

   meetsCriteria[i] = true; 

}


for (int i = 2; i < num / 2; ++i) {

   int j = i + i;


   while (j <= num) 
   {
       meetsCriteria[j] = false;
       j += i;
   }

}


for (int i = 0; i < num; ++i) {

   if (meetsCriteria[i]) 
   {
       Console.WriteLine(i + " meets criteria");
   }

} </codepre>


...do name variables appropriately:

<codepre> for (int Counter1 = 1; Counter1 < num; ++Counter1) {

   isPrime[Counter1] = true; 

}


for (int Counter2 = 2; Counter2 < num / 2; ++Counter2) {

   int factorableNumber = Counter2 + Counter2;


   while (factorableNumber <= num) 
   {
       isPrime[factorableNumber] = false;
       factorableNumber += Counter2;
   }

}


for (int Counter3 = 0; Counter3 < num; ++Counter3) {

   if (isPrime[Counter3]) 
   {
       Console.WriteLine(Counter3 + " is prime.");
   }

} </codepre>

Note: Indexer variables should generally be called Counter1, Counter2, etc. But in cases like this where it isn't quickly obvious what is going on with those loops, it may make sense to reconsider this rule: for instance, Counter1 and Counter3 could be renamed to PrimeCandidate, and Counter2 to Factor to make the code more 'self-documenting'.