Not so long ago, in the comments to the
topic, AlexS expressed the idea of using the agreement on the design in Habré of code examples of the .Net theme written in C #.
I studied a little the available offers from these sources:
submain.com/blog/FreeCVBNETCodingGuidelinesEbookDownload.aspxidesign.net/idesign/DesktopDefault.aspxand compiled a draft that describes the most basic rules for the design of code written in C #.
I suggest:
- discuss this draft;
- make all the necessary changes to it;
- approve as a standard for writing C # code on Habré.
Moreover, I propose to create a document that could be proposed as recommendations of habrahabr comunity for all other C # programmers.
')
Under the cut you will find the text of the draft. I suggest everyone to discuss it and subject to a proper revision.
1. Requirements
1.1 Pascal casing
Names are described:
• all type definitions, including custom classes, enums, events, delegates, and structures;
• enum values;
• readonly fields and constants;
• interfaces;
• methods;
• namespaces;
• properties;
• public fields;
namespace SampleNamespace
{
enum SampleEnum
{
FirstValue,
Secondvalue
}
struct SampleStruct
{
public int FirstField;
public int SecondField;
}
interface ISampleInterface
{
void SampleMethod ();
}
public class SampleClass: SampleInterface
{
const int SampleConstValue = 0xffffff;
readonly int SampleReadonlyField;
public int SampleProperty
{
get ;
set ;
}
public int SamplePublicField;
SampleClass ()
{
SampleReadonlyField = 1;
}
delegate void SampleDelegate ();
event SampleDelegate SampleEvent;
public void SampleMethod ()
{
}
}
} * This source code was highlighted with Source Code Highlighter .
1.2 Camel casing
Names are described:
• local variables;
• method arguments;
• protected fields.
protected int sampleProtectedField;
int SampleMethod ( int sampleArgument)
{
int sampleLocalVariable;
} * This source code was highlighted with Source Code Highlighter .
1.3 Suffixes and Prefixes
The following suffixes and prefixes are used:
• the names of custom exception classes always end with the suffix “Exception”;
• interface names always begin with the prefix “I”;
• user attribute names always end with the “Attribute” suffix;
• delegates of event handlers are always terminated with EventHandler suffix, the names of EventArgs descendant classes always end with EventArgs suffix.
public class SampleException: System. Exception
{
public SampleException ()
{
}
}
interface ISample
{
void SampleMethod ();
}
[System. AttributeUsage (System. AttributeTargets .All, Inherited = false , AllowMultiple = true )]
sealed class SampleAttribute: System. Attribute
{
public SampleAttribute ()
{
}
} public delegate void AnswerCreatedEventHandler ( object sender, AnswerCreatedEventArgs e);
public class AnswerCreatedEventArgs: EventArgs
{
public int reatedId;
public int ParentId;
public string CreatorName;
} * This source code was highlighted with Source Code Highlighter .
* This source code was highlighted with Source Code Highlighter .
1.4 Abbreviations
When using abbreviations in names, two-character abbreviations are subject to capitalization, in other abbreviations only the first character should be reduced to uppercase.
namespace Sample.IO
{
}
class HttpUtil
{
} * This source code was highlighted with Source Code Highlighter .
2. Recommendations
2.1 Naming methods
Use the verb-object construct to name the methods.
ShowUserInfo ()
In the particular case, for methods that return a value, use the verb-object for the verb “Get” in a pair, and for an object, use the description of the return value.
GetUserId ()
2.2 Variables, fields and properties
• When naming variables, avoid using abbreviated variants like
I and
t , use
index and
temp . Do not use the Hungarian notation or use it only for closed members. Do not abbreviate words, use
number , not
num .
• It is recommended for control names to specify prefixes that describe the type of the element. For example: txtSample, lblSample, cmdSample or btnSample. The same recommendation applies to complex local variables: ThisIsLongTypeName tltnSample = new ThisIsLongTypeName ();
• do not use public or protected fields, use properties instead;
• use automatic properties;
• always specify the access modifier private, even if it is allowed to omit it;
• Always initialize variables, even when automatic initialization exists.
2.3 Additional recommendations
• use an empty line between logical sections in the source file, class, method;
• use an intermediate variable to transfer the bool value of the function result to the
if conditional expression;
bool boolVariable = GetBoolValue ();
if (boolVariable)
{
} * This source code was highlighted with Source Code Highlighter .
2.4 The amount of code
• Avoid files with more than 500 lines of code;
• Avoid methods with more than 200 lines of code;
• avoid methods with more than 5 arguments, use structures to transfer a large number of parameters;
• one line of code should not be longer than 120 characters.
3. Controversial points for discussion
3.1 Closed Fields
First option
Private field names always begin with the “m_” prefix; the rest of the name is described using Pascal Casing.
private int m_SamplePrivateField;
Second option
Private field names always begin with the “m” prefix. The rest of the name is described using Pascal Casing.
private int mSamplePrivateField;
The third option (while the most likely at the final version)
Private field names always begin with the “_” prefix. The rest of the name is described using Camel Casing.
private int _samplePrivateField;
3.2 Additional Requirements
• always place opening and closing curly braces on a new line;
• always use curly braces for the if expression, even when only one line of code enters the expression;