Вы находитесь на странице: 1из 66

DOT NET Coding Standards

Page 1 of
40

10
11

Table of Contents
1.

DESIGN GUIDE.................................................................................................................................................................... 5

1.1
Abstractions................................................................................................................................................................. 5
1.2
Inheritance vs. Helpers................................................................................................................................................... 5
1.3
Interfaces vs. Abstract Classes.......................................................................................................................................... 5
1.4
Modifying interfaces....................................................................................................................................................... 6
1.5
Delegates vs. Interfaces.................................................................................................................................................. 6
1.6
Methods vs. Properties.................................................................................................................................................... 6
1.7
Virtual Methods............................................................................................................................................................ 7
1.8
Choosing Types............................................................................................................................................................. 7
1.9
Design-by-Contract........................................................................................................................................................ 7
Object Composition.................................................................................................................................................................................... 7
Object Model & API Design............................................................................................................................................................................ 8
1.12
Asynchronous Programming.............................................................................................................................................. 8
1.13
Multi-Threading............................................................................................................................................................ 8
2

NAMESPACES..................................................................................................................................................................... 9
2.1
2.2

Usage......................................................................................................................................................................... 9
Naming..................................................................................................................................................................... 10

FORMATTING................................................................................................................................................................... 10
3.1
1.1.1
3.2
3.3
3.4
3.5
3.6
3.7
3.8
3.9
3.10
3.11
3.11.1

Indenting and Spacing................................................................................................................................................... 10


Comments.............................................................................................................................................................. 10
Block Comments.......................................................................................................................................................... 10
Single Line Comments................................................................................................................................................... 10
Documentation Comments............................................................................................................................................. 10
Braces...................................................................................................................................................................... 10
Properties.................................................................................................................................................................. 10
Methods.................................................................................................................................................................... 10
Enumerations............................................................................................................................................................. 10
Parentheses............................................................................................................................................................... 11
Empty Lines............................................................................................................................................................... 11
Line Breaking.............................................................................................................................................................. 12
Inter-term spacing....................................................................................................................................................... 13

3.11.2
3.11.3
4

NAMING........................................................................................................................................................................... 15
4.1
4.1.1
4.1.2
4.1.3
4.1.4
1.1.2
4.1.4.1
4.1.4.2
4.1.4.3
4.1.5
4.1.5.1
4.1.5.2
4.1.5.3
4.1.5.4
4.1.5.5
4.1.5.6
4.1.5.7
4.1.5.8
4.1.5.9
4.1.5.10
4.1.5.11

Basic Composition........................................................................................................................................................ 15
Valid Characters.......................................................................................................................................................... 15
General Rules............................................................................................................................................................. 16
Collision and Matching................................................................................................................................................... 16
Capitalization............................................................................................................................................................. 16
Capitalization Styles.................................................................................................................................................. 16
Pascal Casing.............................................................................................................................................................. 16
Camel Casing.............................................................................................................................................................. 17
Upper case................................................................................................................................................................. 17
Naming Guidelines....................................................................................................................................................... 17
Class Naming Guidelines................................................................................................................................................ 17
Interface Naming Guidelines........................................................................................................................................... 17
Enum Naming Guidelines............................................................................................................................................... 18
ReadOnly and Const Field Names..................................................................................................................................... 18
Parameter/non const field Names..................................................................................................................................... 18
Variable Names........................................................................................................................................................... 18
Method Names............................................................................................................................................................ 18
Property Names........................................................................................................................................................... 19
Event Names.............................................................................................................................................................. 20
UI Controls Naming convention........................................................................................................................................ 20
Capitalization summary................................................................................................................................................. 21

DECLARATIONS.................................................................................................................................................................. 24
5.1
5.2
5.3

Table like formatting.................................................................................................................................................... 13


WhiteSpace (or) NewLine (or) LineBrake usage summary........................................................................................................ 13

Number of Declarations per Line...................................................................................................................................... 24


Initialization............................................................................................................................................................... 24
Class and Interface Declarations...................................................................................................................................... 25

STATEMENTS..................................................................................................................................................................... 26
6.1
6.2

Simple Statements....................................................................................................................................................... 26
Return Statements....................................................................................................................................................... 26

ERRORS AND EXCEPTIONS.................................................................................................................................................. 26


7.1
7.2

RESOURCE CLEANUP.......................................................................................................................................................... 29
8.1
8.2
8.3
8.4

Exception Throwing...................................................................................................................................................... 26
Exception Handling...................................................................................................................................................... 27

Try-finally Block.......................................................................................................................................................... 29
Basic Dispose Pattern.................................................................................................................................................... 30
Finalizable Types......................................................................................................................................................... 34
Overriding Dispose....................................................................................................................................................... 38

COMMON ONE LINERS........................................................................................................................................................ 39

1. DESIGN GUIDE

In general, design decisions that involve thinking about the following topics should not be made alone. You should apply these principles to come up
with a design, but should always seek the advice and approval of at least one other team member before proceeding. It is easy to come up with a
document, but the spirit of best coding standards comes from the developers, who adopt the following recommendations.

1.1

ABSTRACTIONS
The first rule of design is dont overdesign. Overdesign leads to a framework that offers unused functionality and has interfaces that are
difficult to understand and implement. Only create abstractions where there will be more than one implementation or where there is a
reasonable need to provide for other implementations in the future.
This leads directly to the second rule of design: dont under-design. Understand your problem domain well enough before starting to code so
that you accommodate reasonably foreseeable additional requirements. For example, whether or not there is a need for multiple
implementations (in which case you should define interfaces) or a need for code sharing (in which case abstract interfaces are in order). You
should create abstractions where they prevent repeated code (applying the DRY principle) or where they provide decoupling.
If you do create an abstraction, make sure that there are tests which run against the abstraction rather than a concrete implementation so
that all future implementations can be tested. For example, database access for a particular database should include an abstraction and
tests for that abstraction that can be used to verify all supported databases.

1.2

INHERITANCE VS. HELPERS


The rule here is to only use inheritance where it makes semantic sense to do so. If two classes could share code because they perform
similar tasks, but arent really related, do not give them a common ancestor just to avoid repeating yourself. Extract the shared code into
a helper class and use that class from both implementations. A helper class can be static, but may also be an instance.

1.3

INTERFACES VS. ABSTRACT CLASSES


Whether or not to use interfaces is a hotly-debated topic. On the one hand, interfaces offer a clean abstraction and interface to a library
component and, on the other hand, they restrict future upgrades by forcing new methods or properties on existing implementations. In a
framework or library, you can safely add members to classes that have descendants in application code without forcing a change in that
application code. However, abstract methodswhich are necessary for very low-level objects because the implementation cant be knownrun
into the same problems as new interface methods. Creating new, virtual methods with no implementation to avoid this problem is also not
recommended, as it fails to impart the intent of the method.

Where interfaces can be useful is in restricting write-access to certain properties or containers. That is, an interface can be declared with
only a getter, but the implementation includes both a getter and setter. This allows an application to set the property when it works with an
internal implementation, but to restrict the code receiving the interface to a read-only property.

1.4

MODIFYING INTERFACES
In general, be extremely careful of modifying interfaces that are used by code not under your control (i.e. code that has shipped and been
integrated into other codebases). If a change needs to be made, it must be very clearly documented in the release notes for the code and
must include tips for implementing / updating the implementation for the interface.
Another solution is to develop a parallel path that consumes a new interface inherited from the existing one.

1.5

DELEGATES VS. INTERFACES


Both delegates and interfaces can be used to connect components in a loosely-coupled way. A delegate is more loosely-coupled than an
interface because it specifies the absolute minimum amount of information needed in order to interoperate whereas an interface forces the
implementing component to satisfy a set of clearly-defined functionality.
If the bridge between two components is truly that of an event sink communicating with an event listener, then you should use event handlers
and delegates to communicate. However, if you start to have multiple such delegate connections between two components, youll want to
improve clarity by defining an interface to more completely describe this relationship.

1.6

METHODS VS. PROPERTIES


Use methods instead of properties in the following situations:
For transformations or conversions, like ToXml() or ToSql()
If the value of the property is not cached internally, but is expensive to calculate, indicate this with a method call instead of a property
(properties generally give the impression that they reference information stored with the object)
If the result is not idempotent (yields the same result no matter how often it is called), it should be a method
If the property returns a copy of an internal state rather than a direct reference; this is especially significant with array properties, where
repeated access is very inefficient.
When a getter is not desired, use a method instead of a write-only property.
For all other situations in which both a property and a method are appropriate, properties have the following advantages over methods:

Properties dont require parentheses and result in cleaner code when called (especially when many are chained together)
It clearly indicates that the value is a logical property of the construct instead of an operation.

1.7

VIRTUAL METHODS
Choose carefully which methods are marked as virtual as they incur design, test and maintenance costs not shared by non-virtual methods.

1.8

CHOOSING TYPES
Use the least-derived possible type for local variables and method parameters; this makes the expected API as explicit and open as possible.
Use existing interfaces wherever possible, even when declaring local or member variables. Interfaces should be useful in most instances;
otherwise theyve probably been designed poorly.
IMessageStore messages = new MessageStore();
IExpressionContext context = new ExpressionContext(this);
Use the actual instantiated class for the member type when you need to access members not available in the interface. Do not modify the
interface solely in order to keep using the interface instead of the class.

1.9

DESIGN-BY-CONTRACT
Use assertions at the beginning of a method to assert preconditions; assert post-conditions if appropriate.
Use Debug.Assert or throw standard system exceptions for pre- and post-conditions
You may throw the exception on the same line as the check, to mirror the formatting of the assertion.
if (connection == null) { throw new ArgumentNullException("connection"); }

If the assertion cannot be formulated in code, add a comment describing it instead


If class invariants are not supported, describe the restrictions in the class documentation or note the invariant in commented form at
the end of the class
All methods and properties used to test pre-conditions must have the same visibility as the method being called.

1.10

OBJECT COMPOSITION

Always declare types explicitly within a namespace. Do not use the default {global} namespace.
Avoid overuse of the public access modifier. Typically fewer than 10% of your types and members will be
Part of a public API, unless you are writing a class library.
Consider using internal or private access modifiers for types and members unless you intend to support
Them as part of a public API.
Never use the protected access modifier within sealed classes unless overriding a protected member of

An inherited type.
Avoid declaring methods with more than 5 parameters. Consider refactoring this code.
Try to replace large parameter-sets (> than 5 parameters) with one or more class or struct parameters
Especially when used in multiple method signatures.
Do not use the new keyword on method and property declarations to hide members of a derived type.
Only use the base keyword when invoking a base class constructor or base implementation within an
Override.
Consider using method overloading instead of the params attribute (but be careful not to break CLS
Compliance of your APIs).
Always validate an enumeration variable or parameter value before consuming it. They may contain any value
That the underlying Enum type (default int) supports.

Example
public void Test(BookCategory cat)
{
if (Enum.IsDefined(typeof(BookCategory), cat))
{}
}

1.11

OBJECT MODEL & API DESIGN

1.12

ASYNCHRONOUS PROGRAMMING

1.13

Always prefer aggregation over inheritance.


Avoid Premature Generalization. Create abstractions only when the intent is understood.
Do the simplest thing that works, then refactor when necessary.
Always make object-behavior transparent to API consumers.
Avoid unexpected side-affects when properties, methods, and constructors are invoked.
Always separate presentation layer from business logic.
Always prefer interfaces over abstract classes.
Try to include the design-pattern names such as Bridge, Adapter, or Factory as a suffix to class names
Where appropriate.
Only make members virtual if they are designed and tested for extensibility.
Refactor often!

Avoid async void. Prefer async Task methods over async void methods
Async all the way. Dont mix blocking and async code
Configure context. Use ConfigureAwait(false) when you can

MULTI-THREADING

Don't use Thread.Abort to terminate other threads. Calling Abort on another thread is akin to throwing an exception on that thread,
without knowing what point that thread has reached in its processing.

Don't use Thread.Suspend and Thread.Resume to synchronize the activities of multiple threads. Do use Mutex, ManualResetEvent,
AutoResetEvent, and Monitor.

Don't control the execution of worker threads from your main program (using events, for example). Instead, design your program so that
worker threads are responsible for waiting until work is available, executing it, and notifying other parts of your program when finished. If
your worker threads do not block, consider using thread pool threads. Monitor.PulseAll is useful in situations where worker threads block.

Don't use types as lock objects. That is, avoid code such as lock(typeof(X)) in C# or SyncLock(GetType(X)) in Visual Basic, or the use of
Monitor.Enter with Type objects. For a given type, there is only one instance of System.Type per application domain. If the type you take a
lock on is public, code other than your own can take locks on it, leading to deadlocks. For additional issues, see Reliability Best Practices.

Use caution when locking on instances, for example lock(this) in C# or SyncLock(Me) in Visual Basic. If other code in your application,
external to the type, takes a lock on the object, deadlocks could occur.

Do ensure that a thread that has entered a monitor always leaves that monitor, even if an exception occurs while the thread is in the
monitor. The C# lock statement and the Visual BasicSyncLock statement provide this behavior automatically, employing a finally block to
ensure that Monitor.Exit is called. If you cannot ensure that Exit will be called, consider changing your design to use Mutex. A mutex is
automatically released when the thread that currently owns it terminates.

Do use multiple threads for tasks that require different resources, and avoid assigning multiple threads to a single resource. For example,
any task involving I/O benefits from having its own thread, because that thread will block during I/O operations and thus allow other
threads to execute. User input is another resource that benefits from a dedicated thread. On a single-processor computer, a task that
involves intensive computation coexists with user input and with tasks that involve I/O, but multiple computation-intensive tasks contend
with each other.

NAMESPACES
2.1

USAGE

Do not use the global namespace; the only exception is for ASP.NET pages that are generated into the global namespace.
Avoid fully-qualified type names; use the using statement instead.
If the IDE inserts a fully-qualified type name in your code, you should fix it. If the unadorned name conflicts with other already-included
namespaces, make an alias for the class with a using clause
Avoid putting a using statement inside a namespace (unless you must do so to resolve a conflict)

2.2

NAMING

Avoid deep namespace-hierarchies (five or more levels) as that makes it difficult to browse and understand.

Avoid making too many namespaces; instead, use catch-all namespace suffixes, like Utilities, Core or General until it is
clearer whether a class or group of classes warrant their own namespace. Refactoring is your friend here.
Do not include the version number in a namespace name.
Use long-lived identifiers in a namespace name.
Namespaces should be plural, as they will contain multiple types
If your framework or application encompasses more than one tier, use the same namespace identifiers for similar tasks. For example,
common data-access code goes in <Application>.Data, but metadata-based data-access code goes in <Application>.<MetaName>.Data
Avoid using reserved namespace names like System because these will conflict with standard .NET namespaces and require resolution
using the global:: namespace prefix.

FORMATTING
The formatting rules were designed for use with C#. Where possible, they should be applied to other languages (CSS, JavaScript, etc.) as well.
3.1

INDENTING AND SPACING

3.2

An indent is two spaces; it is never a tab.


Use a single space after a comma (e.g. between function arguments).
There is no space after the leading parenthesis/bracket or before the closing Parenthesis / bracket
There is no space between a method name and the leading parenthesis, but there is a space before the leading parenthesis of a flow
control statement
Use a single space to surround all2 infix operators; there is no space between a prefix operator (e.g. - or !) and its argument
Do not use spacing to align type members on the same column (e.g. as with the members of an enumerated type)

COMMENTS

BLOCK COMMENTS
Block comments should usually be avoided. For descriptions use of the /// comments to give C# standard descriptions is recommended.
When you wish to use block comments you should use the following style :

/* Line 1
* Line 2

* Line 3
*/
As this will set off the block visually from code for the (human) reader. Alternatively you might use this old fashioned C style for single line
comments, even though it is not recommended. In case you use this style, a line break should follow the comment, as it is hard to see code
proceeded by comments in the same line:
/* blah blah blah */
Block comments may be useful in rare cases, refer to the TechNote 'The fine Art of Commenting' for an example. Generally block comments
are useful for comment out large sections of code.
3.4

SINGLE LINE COMMENTS


You should use the // comment style to "comment out" code. It may be used for commenting sections of code too.
Single line comments must be indented to the indent level when they are used for code documentation. Commented out code should be
commented out in the first line to enhance the visibility of commented out code.
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.

3.5

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:
/// <summary>
/// This is a comment for class
/// </summary>
Multiline XML comments follow this pattern:
///<exception cref="testException">
///This is an exception comment
///thrown for test exception

///</exception>
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 multiline 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>.
Documentation can then be generated using the 'documentation' item in the #develop 'build' menu. The documentation generated is in
HTMLHelp format.
3.6

3.7

BRACES

Curly braces shouldwith a few exceptions outlined belowgo on their own line

A line with only a closing brace should never be preceded by an empty line
A line with only an opening brace should never be followed by an empty line

PROPERTIES

3.8

Simple getters and setters should go on the same line as all brackets
Abstract properties should have get, set and all braces on the same line
Complex getters and setters should have each bracket on its own line
Prefer automatic properties as it saves a lot of typing and vastly improves readability

METHODS
Completely empty functions, like constructors, should have a space between brackets placed on the same line:
SomeClass(string name)
: base(name)
{}

3.9

ENUMERATIONS
Use the trailing comma for the last member of an enumeration; this makes it easier to move them around, if needed.

Page 10 of
40

3.10

PARENTHESES

C# has a different operator precedence than Pascal or C, so you can write


context !=null && context.Count > 0
without confusing the compiler. However, you should use the form
(context != null) && (context.Count > 0)
for legibilitys sake.

Do not use parentheses around the parameter(s) in a lambda expression


To make it more readable, use parentheses around the condition of a ternary expression if it uses an infix operator
return (_value != null) ? Value.ToString() : "NULL";

Prefix operators (e.g. !) and method calls should not have parentheses around them.
return !HasValue ? Value.ToString() : "EMPTY";

3.11

EMPTY LINES
In the following list, the phrase surrounding code refers to a line consisting of more than just an opening or closing brace. That is, no
new line is required when an element is at the beginning or end of a methods or other block-level element.
Always place an empty line in the following places:
Between the file header and the namespace declaration or the first using statement.
Between the last using statement and the namespace declaration.
Between types (classes, structs, interfaces, delegates or enums).
Between public, protected and internal members.
Between preconditions and ensuing code.
Between post-conditions and preceding code.
Between a call to a base method and ensuing code.
Between return statements and surrounding code (this does not apply to return statements at the beginning or end of methods)
Between block constructs (e.g. while loops or switch statements) and surrounding code.

Page 11 of
40

Between documented enum values; undocumented may be grouped together

Page 12 of
40

Between logical groups of code in a method; this notion is subjective and more a matter of style. You should use empty lines to
improve readability, but should not overuse them.
Between the last line of code in a block and a comment for the next block of code.
Between statements that are broken up into multiple lines.
Between a #region tag and the first line of code in that region.
Between the last line of code in a region and the #endregion tag.

Do not place an empty line in the following places:


After another empty line
Between retrieval code and handling for that code. Instead, they should be formatted together.
IMetaReadableObject obj = context.Find<IMetaReadableObject>();
if (obj == null)
{
context.Recorder.Log(Level.Fatal, String.Format("Error!));
return null;
}

3.12

Between any line and a line that has only an opening or closing brace on it (i.e. there should be no leading or trailing newlines in a block)

Between undocumented fields (usually private); if there are many such fields, you may use empty lines to group them by purpose.

LINE BREAKING
Blank lines improve readability. They set 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
Properties
Local variables in a method and its first statement
Logical sections inside a method to improve readability

Note that blank lines must be indented as they would contain a statement this makes insertion in these lines much easier.

3.13

INTER-TERM SPACING
There should be a single space after a comma or a semicolon,
For example:
Don't use :
void TestMethod(a,b,c)
or
void TestMethod( a, b, c )
Recommended to Use :
void TestMethod(a, b, c)

3.14

TABLE LIKE FORMATTING


A logical block of lines should be formatted as a table:
string name = "Mr. Ed";
int
myValue = 5;
LibraryUser libUser = MyClass.GetNewUser();
Use spaces for the table like formatting and not tabs because the table formatting may look strange in
special tab intent levels.

3.15

WHITESPACE (OR) NEWLINE (OR) LINEBRAKE USAGE SUMMARY

No line should exceed 100 characters; use the line-breaking rules listed below to break up a line.
Use line-breaking only when necessary; do not adopt it as standard practice.
If one or more line-breaks is required, use as few as possible
Line-breaking should occur at natural boundaries; the most common such boundary is between parameters in a method call or definition.
Lines after such a line-break at such a boundary should be indented.

The separator (e.g. a comma) between elements formatted onto multiple lines goes on the same line after the element; the IDE is much
more helpful when formatting that way.
The most natural line-breaking boundary is often before and after a list of elements. For example, the following method call has linebreaks at the beginning and end of the parameter list.
people.DataSource = CurrentCompany.Employees.GetList(
connection, metaClass, GetFilter(), null
);

If one of the parameters is much longer, then you add line-breaking between the parameters; in that case, all parameters
are formatted onto their own lines:

people.DataSource = CurrentCompany.Employees.GetList(
connection,
metaClass,
GetFilter("Global.Applications.Updater.PersonList.Search"),
null
);

Note in the examples above that the parameters are indented. If the assignment or method call was longer, they would no longer fit on the
same line. In that case, you should use two levels of indenting.
Application.Model.people.DataSource =
Global.ApplicationEnvironment.CurrentCompany.Employees.GetList(
connection,
metaClass,
GetFilter("Global.Applications.Updater.PersonList.Search"),
null
);

If there is a logical grouping for parameters, you may apply line-breaking at those boundaries instead (breaking the all-on-one-line or eachon-its-own-line rule stated above). For example, the following method specifies Cartesian coordinates:

Geometry.PlotInBox(
"Global.Applications.MainWindow",
topLeft.X, topLeft.Y,
bottomRight.X, bottomRight.Y

);

NAMING
The naming rules were designed for use with C#. Where possible, they should be applied to elements of other languages (CSS,
JavaScript, etc.) as well. Follow all .NET Framework Design Guidelines for both internal and external members. Highlights of these
include:

Do not use Hungarian notation


Do not use a prefix for member variables (_, m_, s_, etc.). If you want to distinguish between local and member
variables you should use this. in C# and Me. in VB.NET.
Do use camelCasing for member variables
Do use camelCasing for parameters
Do use camelCasing for local variables

Do use PascalCasing for function, property, event, and class names


Do prefix interfaces names with I
Do not prefix enums, classes, or delegates with any letter

The reasons to extend the public rules( no Hungarian, no prefix for member variables, etc.) are to produce a consistent source code
appearance. In addition a goal is to have clean readable source. Code legibility should be a primary goal.
4.1

BASIC COMPOSITION

VALID CHARACTERS

Identifiers should contain only alphabetic characters.


The underscore is allowed only as a leading character for fields (or when included in a member generated by the IDE)
Numbers are allowed only for local variables and method parameters and may then only appear as a suffix. Avoid using
numbers wherever possible. (A valid use of a number in an identifier is in a sorting routine that accepts two elements;
in that case, value1 and value2 are appropriate.)

4.3

GENERAL RULES

Names are in US-English (e.g. use color instead of colour).


Names conform to English grammatical conventions (e.g. use ImportableDatabase instead of DatabaseImportable).
Names should be as short as possible without losing meaning.
Prefer whole words or stick to predefined short forms or abbreviations of words
Make sure to capitalize compound words correctly; if the word is not hyphenated, then it does not need a capital letter in the camel- or
Pascal-cased form. For example, metadata is written as Metadata in Pascal-case, not MetaData.
Acronyms should be Pascal-case as well (e.g. Xml or Sql) unless they are only two letters long. Acronyms at the beginning of a
camel-case identifier are always all lowercase.
Identifiers differing only by case may be defined within the same scope only if they identify different language elements (e.g. a local
variable and a property).
public void UpdateLength(int newLength, bool refreshViews)
{
int length = Length;
}

4.4

COLLISION AND MATCHING

4.5

You may not use identifiers that are keywords in C#; neither may you use the @-symbol to turn a keyword into a valid identifier.

Do not name an element with the same identifier as its containing element (e.g. dont create a static class named Expressions within a
namespace called Expressions)
Since C# allows it, you should use the same identifier for a property as its type if that is the most appropriate name in that context
(this is often the case with enum properties)

CAPITALIZATION
The following table lists the capitalization and naming rules for different language elements. Pascal-case capitalizes every individual word
within an identifier, including the first one. Camelcase capitalizes all but the first word in an identifier.

4.6
PASCAL CASING

CAPITALIZATION STYLES

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

4.8

CAMEL CASING
This convention capitalizes the first character of each word except the first one. E.g. testCounter.

4.9

UPPER CASE
Only use all upper case for identifiers if it consists of an abbreviation which is one or two characters long, identifiers of three or more
characters should use Pascal Casing instead.
For Example:
public class Math
{
public const double PI =
3.14; public const string E =
"asdf";
public const int feigenBaumNumber = 91;
}

4.10

NAMING GUIDELINES
Generally the use of underscore characters inside names and naming according to the guidelines for Hungarian notation are considered bad
practice. Hungarian notation is a defined set of pre 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 now is obsolete or at least should be considered deprecated. Using
Hungarian notation is not allowed if you follow this guide.

4.11

CLASS NAMING GUIDELINES

If a class implements a single interface, it should reflect this by incorporating the interface name into its own (e.g. MetaList
implements IList).
Static classes used as toolkits of static functions should use the suffix Tools and should go in a file ending in Tools.cs.

Class names must be nouns or noun phrases.


Use Pascal Casing
Do not use any class prefix

4.12

INTERFACE NAMING GUIDELINES

Name interfaces with nouns or noun phrases or adjectives describing behavior. (Example IComponent or IEnumberable)

4.13

ENUM NAMING GUIDELINES

4.14

Do use descriptive names, which should be enough to determine the variable meaning and its type. But prefer a name thats based on
the parameters meaning.
Use Camel Casing
Prefer whole words instead of abbreviations (use index instead of idx).
Parameter names should be based on their intended use or purpose rather than their type (unless the type indicates the purpose
adequately).
Do not simply repeat the type for the parameter name; use a name that is as short as possible, but doesnt lose meaning. (E.g. a
parameter of type IDataContext should be called context instead of dataContext.
However, if the method also, at some point, makes use of an IViewContext, you should
make the parameter name more specific, using dataContext instead.

VARIABLE NAMES

4.17

Name static fields with nouns, noun phrases or abbreviations for nouns
Use Pascal Casing

PARAMETER/NON CONST FIELD NAMES

4.16

Use Pascal Casing for enum value names and enum type names
Dont prefix (or suffix) a enum type or enum values
Use singular names for enums
Use plural name for bit fields.

READONLY AND CONST FIELD NAMES

4.15

Use Pascal Casing


Use I as prefix for the name, it is followed by a capital letter (first char of the interface name)

Counting variables are preferably called i, j, k, l, m, n when used in 'trivial' counting loops.
Use Camel Casing

METHOD NAMES

Name methods with verbs or verb phrases.


Use Pascal Casing

Method names should not repeat information from the enclosing type. For example, an interface named IMessages should not have a
method named LogMessage; instead name the method Log.

State what a method does; do not describe the parameters (let code-completion and the signature do that for you).
Methods that return values should indicate this in their name, like GetList(), GetItem() or CreateDefaultDatabase(). Though there is
garbage collection in C#, you should still use Get to indicate retrieval of a local value and Create to indicate a factory method, which
always creates a new reference. For example, instead of writing:
public IDataList<GenericObject> GetList(IMetaClass cls)
{
return
ViewApplication.Application.CreateContext<GenericObject>(cls);
}
You should write:
public IDataList<GenericObject> CreateList(IMetaClass cls)
{
return
ViewApplication.Application.CreateContext<GenericObject>(cls);
}

4.18

Avoid defining everything as a noun or a manager. Prefer names that are logically relevant, like Missile.Launch() rather than
MissileLauncher.Execute(missile).
Methods that set a single property value should begin with the verb Set.

PROPERTY NAMES

Name properties using nouns or noun phrases

Use Pascal Casing


Consider naming a property with the same name as its type
Properties should be nouns or adjectives
Prepend Is to the name for Boolean properties only if the intent is unclear without it. The next example shows such a case:
public bool Empty { get; }
public bool IsEmpty { get; }

Although its a property not a method, the first example might still be interpreted as a verb rather than an adjective. The second example
adds the verb Is to avoid confusion, but both formulations are acceptable.

A propertys backing field (if present) must be an underscore followed by the name of the property in camel case.
Use common names, like Item or Value, for accessing the central property of a type

4.19

4.20

Do not include type information in property names. For example, for a property of type IMetaRelation, use the name Relation instead
of the name MetaRelation
Make the identifier as short as possible without losing information. For example, if a class named IViewContext has a property of type
IViewContextHandler, that property should be called Handler.
If there are two properties that could be shortened in this way, then neither of them should be. If the class in the example above has
another property of type IEventListHandler, then the properties should be named something like ViewContextHandler and
EventListhandler, respectively.
Avoid repeating information in a class member that is already in the class name. Suppose, there is an interface named IMessages;
instances of this interface are typically named messages. That interface should not have a property named Messages because that
would result in calls to messages.Messages.Count, which is redundant and not very readable. Instead, name the property something
more semantically relevant, like All, so the call would read messages.All.Count.

EVENT NAMES

Name event handlers with the EventHandler suffix.

Use two parameters named sender and e


Use Pascal Casing
Name event argument classes with the EventArgs suffix.
Name event names that have a concept of pre and post using the present and past tense.
Consider naming events using a verb.

UI CONTROLS NAMING CONVENTION


UI controls would use the following prefixes. The primary purpose was to make code more readable.
Control Type

Prefix

Button

btn

CheckBox

chk

CheckedListBox

lst

ComboBox

cmb

ContextMenu

mnu

DataGrid

dg

DateTimePicker

dtp

Page 20 of
40

Form

suffix: XXXForm

GroupBox

grp

ImageList

iml

Label

lb

ListBox

lst

ListView

lvw

Menu

mnu

MenuItem

mnu

NotificationIcon

nfy

Panel

pnl

PictureBox

pct

ProgressBar

prg

RadioButton

rad

Splitter

spl

StatusBar

sts

TabControl

tab

TabPage

tab

TextBox

tb

Timer

tmr

TreeView

tvw

For example, for the File | Save menu option, the Save MenuItem would be called mnuFileSave.

4.21

CAPITALIZATION SUMMARY
Identifier

Casing

Naming Structure

Class,
Structure

PascalCasing

Noun

Example
public class ComplexNumber {...}
public struct ComplextStruct {...}

Page 20 of
40

Namespace

PascalCasing

Enumeration

PascalCasing

Method

PascalCasing

Public
Property

PascalCasing

Non-public
Field

Event

Noun
Do not use the same name
for a namespace and a type in
that namespace.
Noun
Do name flag enums with
plural nouns or noun phrases
and simple enums with
singular nouns or noun
phrases.
Verb or Verb phrase

namespace
Microsoft.Sample.Windows7

[Flags]
public enum ConsoleModifiers
{ Alt, Control }

public void Print() {...}


public void ProcessItem() {...}

Noun or Adjective
Do name collection
proprieties with a plural
phrase describing the items in
the collection, as opposed to
a singular phrase followed by
List or Collection.
Do name Boolean
proprieties with an
affirmative phrase (CanSeek
instead of CantSeek).
Optionally, you can also
prefix Boolean properties with
Is, Can, or Has but only
where it adds value.
camelCasing or
Noun or Adjective.
_camelCasing Do be consistent in a code
sample when you use the '_'
prefix.

public string CustomerName


public ItemCollection Items
public bool CanRead

PascalCasing

// A close event that is raised after


the window is closed.
public event WindowClosed

Verb or Verb phrase


Do give events names with a
concept of before and after,
using the present and past

private string name;


private string _name;

Page 20 of
40

tense.
Do not use Before or
After prefixes or postfixes
to indicate pre and post
events.
Do add the suffix
EventHandler to names of
delegates that are used in
events.
Do add the suffix
Callback to names of
delegates other than those
used as event handlers.
Do not add the suffix
Delegate to a delegate.

// A close event that is raised before


a window is closed.
public event WindowClosing

Delegate

PascalCasing

Interface

PascalCasing
I prefix

Noun

public interface IDictionary

Constant

PascalCasing for
publicly visible;
camelCasing for
internally
visible;
All capital only
for abbreviation
of one or two
chars long.

Noun

public const string MessageText =


"A";
private const string messageText =
"B";
public const double PI = 3.14159...;

Parameter,
Variable

camelCasing

Noun

int customerID;

Generic
Type
Parameter

PascalCasing
T prefix

Noun
Do name generic type
parameters with descriptive
names, unless a single-letter
name is completely selfexplanatory and a descriptive
name would not add value.

public delegate
WindowClosedEventHandler

T, TItem, TPolicy

Page 20 of
40

Resource

PascalCasing

Do prefix descriptive type


parameter names with T.
You should using T as the
type parameter name for
types with one single-letter
type parameter.
Noun
Do provide descriptive
rather than short identifiers.
Keep them concise where
possible, but do not sacrifice
readability for space.
Do use only alphanumeric
characters and underscores in
naming resources.

ArgumentExceptionInvalidName

DECLARATIONS
5.1

NUMBER OF DECLARATIONS PER LINE


One declaration per line is recommended since it encourages commenting1. In other words,
int level; // indentation level
int size; // size of table
Do not put more than one variable or variables of different types on the same line when declaring them.
Example:
int a, b; //What is 'a'? What does 'b' stand for?
The above example also demonstrates the drawbacks of non-obvious variable names. Be clear when naming variables.

5.2

INITIALIZATION
Try to initialize local variables as soon as they are declared. For example:

Page 20 of
40

string name = LibraryUser.FullName;


or
int currSec = DateTime.Now.Millisecond;
Note: If you initialize a dialog try to use the using statement:
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
...
}
5.3

CLASS AND INTERFACE DECLARATIONS


When coding C# classes and interfaces, the following formatting rules should be followed:

No space between a method name and the parenthesis "(" starting its parameter list.
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.
For example :
class MySample : MyClass, IMyInterface
{
int myInt;
public MySample(int myInt)
{
this.myInt = myInt;
}
void Inc()
{
++myInt;
}
void EmptyMethod()
{

}
}

STATEMENTS
6.1

SIMPLE STATEMENTS
Each line should contain only one statement.

6.2

RETURN STATEMENTS
A return statement should not use outer most parentheses.
Don't use:
return (n * (n + 1) / 2);
Recommended to Use:
return n * (n + 1) / 2;

ERRORS AND EXCEPTIONS


7.1

EXCEPTION THROWING
Do report execution failures by throwing exceptions. Exceptions are the primary means of reporting errors in frameworks. If a member
cannot successfully do what it is designed to do, it should be considered an execution failure and an exception should be thrown. Do not
return error codes.
Do throw the most specific (the most derived) exception that makes sense. For example, throw ArgumentNullException and not its base type
ArgumentException if a null argument is passed. Throwing System.Exception as well as catching System.Exception is nearly always the wrong
thing to do.
Do not use exceptions for the normal flow of control, if possible. Except for system failures and operations with potential race conditions,
you should write code that does not throw exceptions. For example, you can check preconditions before calling a method that may fail and
throw exceptions. For example,
// C# sample:
if (collection != null && !collection.IsReadOnly)
{
collection.Add(additionalNumber);
}

Do not throw exceptions from exception filter blocks. When an exception filter raises an exception, the exception is caught by the CLR,
and the filter returns false. This behavior is indistinguishable from the filter executing and returning false explicitly and is therefore very
difficult to debug.
' VB.NET sample
' This is bad design. The exception filter (When clause)
' may throw an exception when the InnerException property
' returns null
Try
...
Catch e As ArgumentException _
When e.InnerException.Message.StartsWith("File")
...
End Try
Do not explicitly throw exceptions from finally blocks. Implicitly thrown exceptions resulting from calling methods that throw are
acceptable.
7.2

EXCEPTION HANDLING
You should not swallow errors by catching nonspecific exceptions, such as System.Exception, System.SystemException, and so on in .NET
code. Do catch only specific errors that the code knows how to handle. You should catch a more specific exception, or re-throw the general
exception as the last statement in the catch block. There are cases when swallowing errors in applications is acceptable, but such cases are
rare.
Good:
try
{
...
}
catch(System.NullReferenceException exc)
{
...
}

catch(System.ArgumentOutOfRangeException
{
...

exc)

}
catch(System.InvalidCastException exc)
{
...
}
Bad:
try
{
...
}
catch (Exception ex)
{
...
}
Do prefer using an empty throw when catching and re-throwing an exception. This is the best way to preserve the exception call stack.
Good:
try
{
... // Do some reading with the file
}
catch
{
file.Position = position; // Unwind on failure
throw; // Rethrow
}
Bad:
try
{
... // Do some reading with the file
}

catch (Exception ex)


{
file.Position = position; // Unwind on failure

}
8

throw ex; // Rethrow

RESOURCE CLEANUP
Do not force garbage collections with GC.Collect.

8.1

TRY-FINALLY BLOCK
Do use try-finally blocks for cleanup code and try-catch blocks for error recovery code. Do not use catch blocks for cleanup code. Usually,
the cleanup logic rolls back resource (particularly, native resource) allocations. For example,
FileStream stream = null;
try
{
stream = new FileStream(...);
...
}
finally
{
if (stream != null)
{
stream.Close();
}
}
C# and VB.NET provide the using statement that can be used instead of plain try-finally to clean up objects implementing the
IDisposable interface.
// C# sample:
using (FileStream stream = new FileStream(...))
{
...

Many language constructs emit try-finally blocks automatically for you. Examples are C#/VBs using statement, C#s lock
statement, VBs SyncLock statement, C#s foreach statement, and VBs For Each statement.

8.2

BASIC DISPOSE PATTERN


The basic implementation of the pattern involves implementing the System.IDisposable interface and declaring the Dispose(bool) method
that implements all resource cleanup logic to be shared between the Dispose method and the optional finalizer. Please note that this
section does not discuss providing a finalizer. Finalizable types are extensions to this basic pattern and are discussed in the next section.
The following example shows a simple implementation of the basic pattern:
public class DisposableResourceHolder : IDisposable
{
private bool disposed = false;
private SafeHandle resource; // Handle to a resource
public DisposableResourceHolder()
{
this.resource = ... // Allocates the native resource
}
public void DoSomething()
{
if (disposed)
{
throw new ObjectDisposedException(...);
}

// Now call some native methods using the resource


...

public void Dispose()


{
Dispose(true);
GC.SuppressFinalize(this);

Page 30 of
40

Page 30 of
40

protected virtual void Dispose(bool disposing)


{
// Protect from being called multiple times.
if (disposed)
{
return;
}
if (disposing)
{
// Clean up all managed resources.
if (resource != null)
{
resource.Dispose();
}
}

disposed = true;
}

Do implement the Basic Dispose Pattern on types containing instances of disposable types.

Do extend the Basic Dispose Pattern to provide a finalizer on types holding resources that need to be freed explicitly and that do not have
finalizers. For example, the pattern should be implemented on types storing unmanaged memory buffers.
You should implement the Basic Dispose Pattern on classes that themselves dont hold unmanaged resources or disposable objects but are
likely to have subtypes that do. A great example of this is the System.IO.Stream class. Although it is an abstract base class that doesnt hold
any resources, most of its subclasses do and because of this, it implements this pattern.
Do declare a protected virtual void Dispose(bool disposing) method to centralize all logic related to releasing unmanaged resources. All
resource cleanup should occur in this method. The method is called from both the finalizer and the IDisposable.Dispose method. The

Page 31 of
40

parameter will be false if being invoked from inside a finalizer. It should be used to ensure any code running during finalization is not accessing
other finalizable objects. Details of implementing finalizers are described in the next section.
protected virtual void Dispose(bool disposing)

Page 32 of
40

{
// Protect from being called multiple times.
if (disposed)
{
return;
}
if (disposing)
{
// Clean up all managed resources.
if (resource != null)
{
resource.Dispose();
}
}
disposed = true;
}
Do implement the IDisposable interface by simply calling Dispose(true) followed by GC.SuppressFinalize(this). The call to SuppressFinalize
should only occur if Dispose(true) executes successfully.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
Do not make the parameterless Dispose method virtual. The Dispose(bool) method is the one that should be overridden by subclasses.
You should not throw an exception from within Dispose(bool) except under critical situations where the containing process has been
corrupted (leaks, inconsistent shared state, etc.). Users expect that a call to Dispose would not raise an exception. For example, consider
the manual try-finally in this C# snippet:

TextReader tr = new StreamReader(File.OpenRead("foo.txt"));


try
{

// Do some stuff
}
finally
{
tr.Dispose();
// More stuff
}
If Dispose could raise an exception, further finally block cleanup logic will not execute. To work around this, the user would need to wrap
every call to Dispose (within their finally block!) in a try block, which leads to very complex cleanup handlers. If executing a Dispose(bool
disposing) method, never throw an exception if disposing is false. Doing so will terminate the process if executing inside a finalizer context.
Do throw an ObjectDisposedException from any member that cannot be used after the object has been disposed.
public class DisposableResourceHolder : IDisposable
{
private bool disposed = false;
private SafeHandle resource; // Handle to a resource
public void DoSomething()
{
if (disposed)
{
throw new ObjectDisposedException(...);
}
// Now call some native methods using the resource
...
}
protected virtual void Dispose(bool disposing)
{
if (disposed)
{

return;

// Cleanup
...
disposed = true;
}
}

8.3

FINALIZABLE TYPES
Finalizable types are types that extend the Basic Dispose Pattern by overriding the finalizer and providing finalization code path in
the Dispose(bool) method. The following code shows an example of a finalizable type:
public class ComplexResourceHolder : IDisposable
{
bool disposed = false;
private IntPtr buffer; // Unmanaged memory buffer
private SafeHandle resource; // Disposable handle to a resource
public ComplexResourceHolder()
{
this.buffer = ... // Allocates memory
this.resource = ... // Allocates the resource
}
public void DoSomething()
{
if (disposed)
{
throw new ObjectDisposedException(...);
}
// Now call some native methods using the resource
...
}

~ComplexResourceHolder()
{

Dispose(false);

public void Dispose()


{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
// Protect from being called multiple times.
if (disposed)
{
return;
}
if (disposing)
{
// Clean up all managed resources.
if (resource != null)
{
resource.Dispose();
}
}
// Clean up all native resources.
ReleaseBuffer(buffer);

disposed = true;

}
Do make a type finalizable, if the type is responsible for releasing an unmanaged resource that does not have its own finalizer. When
implementing the finalizer, simply call Dispose(false) and place all resource cleanup logic inside the Dispose(bool disposing) method.

public class ComplexResourceHolder : IDisposable

...
~ComplexResourceHolder()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
...
}

}
Do be very careful to make type finalizable. Carefully consider any case in which you think a finalizer is needed. There is a real cost
associated with instances with finalizers, from both a performance and code complexity standpoint.
Do implement the Basic Dispose Pattern on every finalizable type. See the previous section for details on the basic pattern. This gives users
of the type a means to explicitly perform deterministic cleanup of those same resources for which the finalizer is responsible.
You should create and use a critical finalizable object (a type with a type hierarchy that contains CriticalFinalizerObject) for situations in
which a finalizer absolutely must execute even in the face of forced application domain unloads and thread aborts.
Do prefer resource wrappers based on SafeHandle or SafeHandleZeroOrMinusOneIsInvalid (for Win32 resource handle whose value of either 0
or -1 indicates an invalid handle) to writing finalizer by you to encapsulate unmanaged resources where possible, in which case a finalizer
becomes unnecessary because the wrapper is responsible for its own resource cleanup. Safe handles implement the IDisposable interface,
and inherit from CriticalFinalizerObject so the finalizer logic will absolutely execute even in the face of forced application domain unloads
and thread aborts.
/// <summary>
/// Represents a wrapper class for a pipe handle.
/// </summary>
[SecurityCritical(SecurityCriticalScope.Everything),

HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true),


SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
internal sealed class SafePipeHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private SafePipeHandle()

{
}

: base(true)

public SafePipeHandle(IntPtr preexistingHandle, bool ownsHandle)


: base(ownsHandle)
{
base.SetHandle(preexistingHandle);
}
[ReliabilityContract(Consistency.WillNotCorruptState,
Cer.Success),
DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
protected override bool ReleaseHandle()
{
return CloseHandle(base.handle);
}
}
/// <summary>
/// Represents a wrapper class for a local memory pointer.
/// </summary>
[SuppressUnmanagedCodeSecurity,
HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)]
internal sealed class SafeLocalMemHandle : SafeHandleZeroOrMinusOneIsInvalid
{
public SafeLocalMemHandle()
: base(true)
{
}
public SafeLocalMemHandle(IntPtr preexistingHandle, bool ownsHandle)
: base(ownsHandle)

{
base.SetHandle(preexistingHandle);

}
[ReliabilityContract(Consistency.WillNotCorruptState,
Cer.Success),
DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr LocalFree(IntPtr hMem);

protected override bool ReleaseHandle()


{
return (LocalFree(base.handle) == IntPtr.Zero);
}

Do not access any finalizable objects in the finalizer code path, as there is significant risk that they will have already been finalized. For
example, a finalizable object A that has a reference to another finalizable object B cannot reliably use B in As finalizer, or vice versa.
Finalizers are called in a random order (short of a weak ordering guarantee for critical finalization).
It is OK to touch unboxed value type fields.
Also, be aware that objects stored in static variables will get collected at certain points during an application domain unload or while
exiting the process. Accessing a static variable that refers to a finalizable object (or calling a static method that might use values stored
in static variables) might not be safe if Environment.HasShutdownStarted returns true.
Do not let exceptions escape from the finalizer logic, except for system-critical failures. If an exception is thrown from a finalizer, the
CLR may shut down the entire process preventing other finalizers from executing and resources from being released in a controlled manner.

8.4

OVERRIDING DISPOSE
If you're inheriting from a base class that implements IDisposable, you must implement IDisposable also. Always call your base class's
Dispose(bool) so it cleans up.
public class DisposableBase : IDisposable
{
~DisposableBase()
{

Dispose(false);
}

public void Dispose()


{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
// ...
}
}
public class DisposableSubclass : DisposableBase
{
protected override void Dispose(bool disposing)
{
try
{
if (disposing)
{
// Clean up managed resources.
}
// Clean up native resources.
}
finally
{
base.Dispose(disposing);
}
}
9

COMMON ONE LINERS

1.

Use long names for variables

2. Initialize variables at the time of declaration

3. Use .Equals instead of ==


4. Use conditional operator ?: instead of IF
5. Use ?? when expecting the null reference
6. Use .Length() comparison to validate string with values
7. Use StringBuilder instead of strings concatenation
8. Use StringBuilder replace instead of string.Replace
9. Use single line assignments for common values
10. Avoid try catch as much possible
11. Organize Usings and remove & sort the references
12. Use white spaces within every expression
13. Separate user methods from system generated methods. Use of Region
14. Give Author details on every page
15. Maintain the history of modification
16. Write the code in as small reusable methods as possible.
17. Never assign objects to null when they are within the loop
18. If you can use the GC.KeepAlive, make the best use of it
19. Try to separate the Finalize method into a different class and instantiate in the caller class that implements the IDisposable interface
20. Make use of WeakReference to avoid the multiple connections / reads from static content
21. Use int.TryParse, instead of Convert.ToInt or int.Parse Never & Ever Trust
the User Input, do use Encoding where ever necessary

Page 40 of
40

Вам также может понравиться