Encore C# Programming Guidelines Version 1.0.0 October 24, 2003
STP023100.doc
Kundana Lal 404-338-5630 Syntel Vicky Murphy 404-338-5618 Revenue Cycle New Development
Encore
Date 10/24/2003
C# Programming Guidelines
Version 1.0.0
Affected Pages All
Table 1.0
Description of Changes Made Initial Release
Revision History
Copyright © 2008 McKesson Corporation and/or one of its subsidiaries. All Rights Reserved. Use of this documentation and related software is governed by a license agreement. This documentation and related software contain confidential, proprietary and trade secret information of McKesson Information Solutions and are protected under United States and international copyright and other intellectual property laws. Use, disclosure, reproduction, modification, distribution, or storage in a retrieval system in any form or by any means is prohibited without the prior express written permission of McKesson
Version 1.0.0
10/20/2003 Confidential & Proprietary
ii
Encore
C# Programming Guidelines
Information Solutions. This documentation and related software are subject to change without notice.
Approvals By signing below, I agree that I have read and approved this document and will abide by the processes stated herein.
___________________________________________ Vice-President Product Development
____________________ Date
___________________________________________ Vice-President Research & Development
____________________ Date
___________________________________________ SQA Director
____________________ Date
Version 1.0.0
10/20/2003 Confidential & Proprietary
iii
Encore
C# Programming Guidelines
TABLE OF CONTENTS Encore........................................................................................................................................ ......i C# Programming Guidelines......................................................................................... ...................i Table 1.0 Revision History..................................................................... ........................ii Approvals................................................................................................................... .................iii TABLE OF CONTENTS.......................................................................................... ....................iv Purpose & Scope.............................................................................................................. ..............1 Process............................................................................................................... ........................1 Guidelines........................................................................................................................ ........1 Naming Conventions............................................................................................ ................1 Case Sensitivity.............................................................................................. ..................1 Abbreviations....................................................................................................... .............2 Word Choice....................................................................................................... ..............2 File Organization............................................................................................................ ...3 C# Source Files............................................................................................. ...................3 Control Flow..................................................................................................................... .5 The for Statement.............................................................................. ...........................5 The foreach Statement........................................................................................... .......5 The while Statement.......................................................................... ...........................6 The do Statement....................................................................................................... ...6 Size................................................................................................................................. ..7 Class Size.................................................................................................... .................7 Method Size................................................................................................ ..................7 Sizing Metrics......................................................................................................... .......7 Declaration........................................................................................... ............................7 Number Per Line........................................................................................... ................7 Miscellaneous........................................................................................................... ...............9 Import Classes.................................................................................................. ...................9 Threading Design Guidelines.............................................................................. .................9 Guidelines for Casting Types................................................................................... ...........12 Guidelines for Asynchronous Programming............................................... ........................12 General Usage Guideline............................................................................. ......................13 References........................................................................................................ ........................13
Version 1.0.0
10/20/2003 Confidential & Proprietary
iv
Encore
C# Programming Guidelines
Purpose & Scope This document is to be used as the reference for C# programming guidelines for the Encore project. The .NET framework's managed environment allows developers to improve their programming model to support a wide range of functionality. The goal of the .NET framework design guidelines is to encourage consistency and predictability in public APIs while enabling Web and crosslanguage integration. It is strongly recommended you follow these design guidelines when developing classes and components that extend the .NET framework. Inconsistent design adversely affects developer productivity. Development tools and addins can turn some of these guidelines into de facto prescriptive rules, and reduce the value of nonconforming components. Nonconforming components will function, but not to their full potential.
Process Guidelines Naming Conventions Case Sensitivity To avoid confusion and guarantee crosslanguage interoperation, follow these rules regarding the use of case sensitivity: •
Do not use names that require case sensitivity. Components must be fully usable from both casesensitive and caseinsensitive languages. Case insensitive languages cannot distinguish between two names within the same context that differ only by case. Therefore, avoid this situation in the components or classes being coded.
•
Do not create two namespaces with names that differ only by case. For example, a caseinsensitive language cannot distinguish between the following two namespace declarations:
•
Version 1.0.0
namespace ee.cummings;
namespace Ee.Cummings;
Do not create a function with parameter names that differ only by case. The following example is incorrect.
10/20/2003 Confidential & Proprietary
Page 1 of 9
Encore
C# Programming Guidelines
•
•
•
void MyFunction(string a, string A)
Do not create a namespace with type names that differ only by case. In the following example, Point p and POINT p are inappropriate type names because they differ only by case.
System.Windows.Forms.Point p
System.Windows.Forms.POINT p
Do not create a type with property names that differ only by case. In the following example, int Color and int COLOR are inappropriate property names because they differ only by case.
int Color {get, set}
int COLOR {get, set}
Do not create a type with method names that differ only by case. In the following example, calculate and Calculate are inappropriate method names because they differ only by case.
void calculate()
void Calculate()
Abbreviations To avoid confusion and guarantee crosslanguage interoperation, follow these rules regarding the use of abbreviations: •
Do not use abbreviations or contractions as parts of identifier names. For example, use GetWindow instead of GetWin.
•
Do not use acronyms that are not generally accepted in the computing field. Where appropriate, use wellknown acronyms to replace lengthy phrase names. For example, use UI for User Interface and OLAP for Online Analytical Processing. When using acronyms, use Pascal case or camel case for acronyms more than two characters long. For example, use HtmlButton or htmlButton. Capitalize acronyms that consist of only two characters, such as System.IO instead of System.Io.
Word Choice Avoid using class names that duplicate commonly used .NET framework namespaces. For example, do not use any of the following names as a class name: System, Collections, Forms, or UI.
Version 1.0.0
10/20/2003 Confidential & Proprietary
Page 2 of 10
Encore
C# Programming Guidelines
In addition, avoid using identifiers that conflict with the following keywords:
AddHandler AddressOf Alias And Ansi As Assembly Auto Base Boolean ByRef Byte ByVal Call
CShort CSng CStr CType Date Decimal Declare Default Delegate Dim Do Double Each Else
For Friend Function Get GetType Goto Handles If Implements Imports In Inherits instanceof Integer
Namespace New Next Not Nothing NotInheritable NotOverridable Object On Option Optional Or Overloads Overridable
Case Catch CBool CByte CChar CDate CDbl CDec Char CInt Class CLng CObj Const
ElseIf End Enum Erase Error eval Event Exit extends ExternalSource False Finalize Finally Float
Interface Is Let Lib Like Long Loop Me Mod Module MustInherit MustOverride MyBase MyClass
Overrides package ParamArray Preserve Private Property Protected Public RaiseEvent ReadOnly ReDim Region REM RemoveHandler
Resume Return Select Set Shadows Shared Short Single Static Step Stop String Structure Sub SyncLoc k Then Throw To True Try TypeOf Unicode Until var volatile When While With
WithEvents WriteOnly Xor
File Organization A file consists of sections that should be separated by blank lines and optional comments identifying each section.
C# Source Files Each C# source file contains a single public class or interface. When private classes and interfaces are associated with a public class, these can be put in the
Version 1.0.0
10/20/2003 Confidential & Proprietary
Page 3 of 10
Encore
C# Programming Guidelines
same source file as the public class. The public class should be the first class or interface in the file. C# source files should have the following ordering: •
Beginning Comments
•
Import statements
•
Namespace, Class and interface declarations
•
Class (static) variables. The order of these variables should be public, protected and then private
•
Instance variables. The order of these variables should be public, protected and then private
•
Constructors
•
Methods These should be grouped by functionality.
Version 1.0.0
10/20/2003 Confidential & Proprietary
Page 4 of 10
Encore
C# Programming Guidelines
Control Flow Where to use for loop instead of a while loop? Basically, use a for loop if it’s known how many times the loop is going to occur. If the loop is based on a constant value or a user inputted value, then the program will "know" how many times it will loop before it starts looping even if its not know what the user will input. for loops are preferred because the syntax automatically initializes the counter variable, increments it, and checks to see if the end of the number of iterations has been reached. The for Statement Use the for statement only when a variable runs from somewhere with some constant increment or decrement. Example: for (int i = 0; i < temperatures.Count; i++) { temperatureSum += (int) temperatures[i]; }
As for the if statement, execution statements should always be enclosed within curly braces. The foreach Statement Use the foreach statement to iterate through a collection that does not need to be changed. Example: foreach (int temperature in temperatures) { temperatureSum += temperature; }
As for the for statement, execution statements should always be enclosed within curly braces. NOTE: Using the foreach statement to change a collection may cause unpredictable side effects.
Version 1.0.0
10/20/2003 Confidential & Proprietary
Page 5 of 10
Encore
C# Programming Guidelines
The while Statement Use the while statement to execute a statement until a specified expression evaluates to false: [C#] while (true) { ... if (DetectTemperature != null) { DetectTemperature(this, args); } ... }
As for the foreach statement, execution statements should always be enclosed within curly braces. NOTE: If the specified expression never evaluates to true, the statement will never be executed. The do Statement Use the do statement to execute a statement repeatedly until a specified expression evaluates to false. The statement will execute at least one time even if the expression never evaluates to true. [C#] do {
... line = Console.ReadLine();
switch (line) { ... case CommandExit: exit = true; break; ... } } while (!exit);
As for the while statement, execution statements should always be enclosed within curly braces.
Version 1.0.0
10/20/2003 Confidential & Proprietary
Page 6 of 10
Encore
C# Programming Guidelines
Size Class Size •
The number of nonstatic methods generally should not exceed 20 for a class that implements core business functionality but on an average should be around 12. The number of nonstatic methods should not exceed 40 for a User Interface class but on an average should be around 25.
•
The number of static methods should not exceed 4 for a class.
•
Multiple classes of this size are more desirable and enable efficient debugging when compared to large classes. By following an objectoriented approach this should be implemented.
Method Size •
The size of a method ideally should not cross 20 to 25 statements; the number of method calls within a method should not exceed 7 to 9.
Sizing Metrics Make sure that the following sizing guideline is followed •
One class per source file, class name should match the file name.
•
Methods per class should not exceed 25.
•
Cyclomatic complexity per method should not be more than 9.
•
Cyclomatic complexity of a function is defined as the number of independent paths the program can take during execution of the function. The complexity level is by no means an absolute measure of the algorithmic complexity of the function, it does however provide a good starting point for which functions to look at for further optimization.
•
Number of lines per method not to exceed 5075.
•
Number of lines in a class should be between 500 to 700 lines of code.
Declaration Number Per Line One declaration per line is recommended since it encourages commenting. Example:
Version 1.0.0
10/20/2003 Confidential & Proprietary
Page 7 of 10
Encore
C# Programming Guidelines String strChargeCode; // Charge Code String strPricingLevel; // Pricing Level
Version 1.0.0
10/20/2003 Confidential & Proprietary
Page 8 of 10
Encore
C# Programming Guidelines
Miscellaneous Import Classes Import only the classes that are required from a namespace. The import statements must follow the package statement. Import statements should be sorted with the most fundamental packages first, and grouped with associated packages together and one blank line between groups. Example: using System.IO; using System.Net;
Threading Design Guidelines The following rules outline the design guidelines for implementing threading: •
Avoid providing static methods that alter static state. In common server scenarios, static state is shared across requests, which means multiple threads can execute that code at the same time. This opens up the possibility for threading bugs. Consider using a design pattern that encapsulates data into instances that are not shared across requests.
•
Static state must be thread safe.
•
Instance state does not need to be thread safe. By default, class libraries should not be thread safe. Adding locks to create threadsafe code decreases performance, increases lock contention, and creates the possibility for deadlock bugs to occur. In common application models, only one thread at a time executes user code, which minimizes the need for thread safety. For this reason, the .NET Framework class libraries are not thread safe by default. When providing a threadsafe version, provide a static Synchronized method that returns a threadsafe instance of a type. For an example, see the System.Collections.ArrayList.Synchronized Method and the System.Collections.ArrayList.IsSynchronized Method.
•
Version 1.0.0
Design libraries with consideration for the stress of running in a server scenario. Avoid taking locks whenever possible.
10/20/2003 Confidential & Proprietary
Page 9 of 10
Encore
C# Programming Guidelines
•
Be aware of method calls in locked sections. Deadlocks can result when a static method in class A calls static methods in class B and vice versa. If A and B both synchronize their static methods, this will cause a deadlock.
•
Performance issues can result when a static method in class A calls a static method in class A. If these methods are not factored correctly, performance will suffer because there will be a large amount of redundant synchronization. Excessive use of finegrained synchronization might negatively impact performance. In addition, it might have a significant negative impact on scalability.
•
Be aware of issues with the lock statement (SyncLock in Visual Basic). It is tempting to use the lock statement to solve all threading problems. However, the System.Threading.Interlocked Class is superior for updates that must be atomic. It executes a single lock prefix if there is no contention. In a code review, watch out for instances like the one shown in the following example.
Example: lock(this) { myField++; }
If we replace the previous example with the following one, it will improve performance. Example: System.Threading.Interlocked.Increment(myField);
Another example is to update an object type variable only if it is null (Nothing in Visual Basic). Use the following code to update the variable and make the code thread safe. Example: if (x == null) { lock (this) { if (x == null) { x = y; } } }
Version 1.0.0
10/20/2003 Confidential & Proprietary
Page 10 of 10
Encore
C# Programming Guidelines
Improve the performance of the previous sample by replacing it with the following code. Example: System.Threading.Interlocked.CompareExchange(ref x, y, null);
•
Version 1.0.0
Avoid the need for synchronization if possible. For high traffic scenarios, it is best to avoid synchronization. Wherever possible, tolerate race conditions rather than trying to eliminate them.
10/20/2003 Confidential & Proprietary
Page 11 of 10
Encore
C# Programming Guidelines
Guidelines for Casting Types The following rules outline the usage guidelines for casts: •
Do not allow implicit casts that will result in a loss of precision. For example, there should not be an implicit cast from Double to Int32, but there might be one from Int32 to Int64.
•
Do not throw exceptions from implicit casts because it is very difficult for the developer to understand what is happening.
•
Provide casts that operate on an entire object. The value that is cast should represent the entire object, not a member of an object. For example, it is not appropriate for a Button to cast to a string by returning its caption.
•
Do not generate a semantically different value. For example, it is appropriate to convert a DateTime or TimeSpan into an Int32. The Int32 still represents the time or duration. It does not, however, make sense to cast a string such as "HelloWorld" into a Bitmap object.
Guidelines for Asynchronous Programming Asynchronous programming is a feature supported by many areas of the common language runtime, such as Remoting, ASP.NET, and Windows Forms. Asynchronous programming is a core concept in the .NET Framework. This topic introduces the design pattern for asynchronous programming. The philosophy behind these guidelines is as follows: •
The client should decide whether a particular call should be asynchronous.
•
It is not necessary for a server to do additional programming in order to support its clients' asynchronous behavior. The runtime should be able to manage the difference between the client and server views. As a result, the situation where the server has to implement IDispatch and do a large amount of work to support dynamic invocation by clients is avoided.
•
The server can choose to explicitly support asynchronous behavior either because it can implement asynchronous behavior more efficiently than a general architecture, or because it wants to support only asynchronous behavior by its clients. It is recommended that such servers follow the design pattern outlined in this document for exposing asynchronous operations.
Version 1.0.0
10/20/2003 Confidential & Proprietary
Page 12 of 10
Encore
C# Programming Guidelines
•
Type safety must be enforced.
•
The runtime provides the necessary services to support the asynchronous programming model. These services include the following:
Synchronization primitives, such as critical sections and ReaderWriterLock instances.
Synchronization constructs such as containers that support the WaitForMultipleObjects method.
Thread pools.
Exposure to the underlying infrastructure, such as Message and ThreadPool objects.
General Usage Guideline Make sure these usage guidelines are followed: •
The class has tidy imports.
•
The class is grouped under a functional namespace.
•
The class contains a default constructor.
•
The class starts with comments (see comments section of “C# Programming Standard”).
•
Calls within the class to static methods of another class are done using the fully qualified name.
•
The class contains standard case statements for switch statements.
•
Unused objects/variables are cleaned up within the class.
•
The use of “goto” is avoided.
•
Try catch blocks are decorated only when there is a possibility of an exception.
•
Common objects should be part of a static class.
References •
Microsoft Developer Network (MSDN)
•
Application Architecture for .NET (Microsoft press)
Version 1.0.0
10/20/2003 Confidential & Proprietary
Page 13 of 10
Encore
C# Programming Guidelines
•
Version 1.0.0
http://www.idesign.net .
10/20/2003 Confidential & Proprietary
Page 14 of 10