Best Practices of Coding

Quality makes an application a masterpiece and it's the responsibility of the developer to focus more on high-quality code. This document covers a few recommendations to leverage the quality of the code in .NET using FXCop 1.30 and how to write custom rules through an introspection engine.

In my view, quality software should work immaculately, with zero bugs. To make a high-quality application, you must consider a few points, such as code clarity, straightforwardness, modularity, layering, design, efficiency, best coding practices and so on. The following are a few recommendations/suggestions to maintain a good and quality application.

  • Make your coding very simple, in other words don't use ten lines of code for something you can do in five in another way. Make the extra effort to be reduce the size for better coding; just try to minimize the coding and the functions that span pages. Simplicity, proper code organization and good design makes your code more reliable and bug-free.

  • Make your coding more clear (for readability); for this you must provide comments, follow naming conventions (as suggested by the document of the specific language) and provide a proper name to variables and so on.

  • Make your program modular, break your large system into small blocks that helps to make blocks (components) reusable.

  • Make your application layered, for example a document / view framework, where some part of your application responsibility is to store the data and another part renders the data and another part handles the user's inputs through a menu/status bar and so on. That means that a higher layer calls lower layers that raises events (calls go down; events go up). Lower layers should never know what higher ones are up to. The essence of an event/callback is to provide blind upward notification. If your document calls the frame directly then that means something is buggy. Modules and layers are defined by APIs with proper boundaries.

  • You must spend more time to define a strategy for your application before implementation of the thumb rule of spending 50% of your total project time for design, you should have a high-level design or a low-level design and Functional Specification and proof of concepts and so on.

  • Performance is one of the key factors for quality software, this makes your application faster and more economical; try to optimize the code for better performance. Of course it's very difficult to focus on optimization and fine tuning at the implementation level but you must plan for performance at a high level. The main point is you must consider the optimization and fine-tuning of your application to make a high-standard application. If you do not consider the performance then it leads to project failure or you need to consider additional people resources and hardware resources. This again increases the project cost that leads to loss of competitiveness and the very important thing, poor performance, leads to damaged customer relations.
    There are many other points to be considered, like security, design patterns (proven concepts) and so on but it depends upon your application requirements. Now I will explain how to avoid bad coding in .NET.

Ask the expert

Whenever we talk about bad coding, one tool comes to our mind, FXCop. For those new to FXCop, it is a free code analysis tool (open source) from Microsoft that analyzes your compiled .NET assemblies for compliance with recommended programming practices. Let me give you a brief history of FXCop. The FX in FXCop stands for Framework as in .NET Framework. Actually its original name was UrtCop (Universal Run Time), the old name of the CLR. The full name is Framework Cop and in short we call it FXCop. The next question is, how and why FXCop. FXCop was created to address the goal of ensuring a consistent look and feel for a brand-new public API of the .NET Framework. During the development process, it became clear the application was also useful for uncovering API usage and general correctness problems. The tool is possible due to key features of the .NET Framework that make signatures, and even Intermediate Language code itself, easily discoverable. FxCop is a case study of the time-to-develop benefits of the .NET Framework. We're pretty proud that it has achieved functionality in an extremely short development time, functionality that is similar to other tools (targeted toward unmanaged binaries). This is where FXCop is useful.You can download this tool from http://www.gotdotnet.com/team/fxcop.

One of the rules of thumb of coding standards has been around as long as programming and development has existed. FXCop only targets .NET code. You can operate FXCop in two modes, either with a GUI or in command-line mode. Microsoft has obviously made a huge investment in .NET and in promulgating best .NET coding practices through the .NET Framework Design Guidelines, that you can find at Design Guidelines for Class Library Developers. Internally, Microsoft wanted to ensure their own developers followed the rules for consistency and maintainability. To enforce the Design Guidelines they devised a solution, out of which sprang FxCop. The purpose of FxCop is to make it easy to comply by scanning compiled assemblies and creating a report that details coding errors (called violations) and suggests code fixes and improvements. Behind the scenes, FXCop uses reflection techniques to read the code of your assembly and process against predefined rules (around 200+ rules are defined ) categorized as naming conventions, library design, localization, security, performance and many more. I will not explain these rules in detail except you can get the details from the FXCop documentation. It checks the code for compliance with these rules. Most of the coding practices are also available in the MSDN site. For the Design and Naming Guidelines refer to:

http://msdn.microsoft.com/library/en-us/cpgenref/html/cpconnetframeworkdesignguidelines.asp or http://msdn.microsoft.com/library/en-us/cpgenref/html/cpconnamingguidelines.asp

and for the Secure Coding Guidelines refer to:

http://msdn.microsoft.com/library/en-us/dnnetsec/html/seccodeguide.asp

To start with FXCop, let's write a sample application and run it under FXCop. To check the best coding practices, have a look at the sample code.

using System;
namespace MySample
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class sampleClass
{
/// <summary>
/// The main entry point for the application.
/// </summary>
///
private string myString = "";
private int myInterger =0;
public string myValue
{
set
{
myString=
value;
}
}
public void FillIntVal(int externalValue)
{
myInterger= externalValue;
}
public int GetIntVal()
{
return myInterger;
}
[STAThread]
static void Main(string[] args)
{
sampleClass objSample =
new sampleClass();
objSample.FillIntVal(10);
Console.WriteLine(objSample.myInterger.ToString());
}
}
}

Now compile the code and generate the assembly to test it in FXCop. The GUI version of FxCop has two panes that are easy to navigate. To analyze an assembly, you simply select "Add Assembly" from the Project menu (not File). To see the rules that FxCop will apply, click the Rules tab, that lists them by category. To make changes, click on the category name and select or deselect the rules you want to apply. The FXCop 1.30 has 6 additional new rules overall. Now we have 12 rules. The yellow highlighted codes are the bad coding practices. The defects are:

  • The class name does not follow the camel casing naming convention.
  • Similar the property name does not follow the camel casing naming convention.
  • The next defect is considered a property when it does not take a parameter and returns a value directly or does a minimum of operations for returning the value.
  • The next defect is the sample class has a set property and does not have a get property.

If you look at the inside of FXCop then you see it actually uses reflection to read the classes in an assembly and compares the rules with the code to determine compliance with the rules. Then it logs the defects. Until now FXCop provides around 200+ rules that incorporate most of the best practices. The new version of FXCop includes around 43 rules and all of them are really handy, like "avoid unnecessary string creation" or "do not raise a reserved exception type" and so on. But sometimes you need additional rules specific to your project. In order to implement this, FXCop provides an option to write custom rules using the FXCop SDK. The earlier version of FXCop (v1.23 ) uses a reflection mechanism to scan the managed assembly, but in FXCop 1.30 that is totally obsolete. Instead Microsoft introduced the Introspection Engine. The reason is, reflection is very slow, around 400 times as slow as a regular function call. One performance trick that I discovered is that a delegate can be constructed from a MethodInfo, by calling one of the Delegate static methods, allowing for a direct call to be made using the correct signature. Introspection that was described as a new faster, engine for performing Reflection on .NET classes. The main advantages of the Introspection engine is it performs more extensive analysis than reflection, multithreading, analysis of assemblies of various versions of the framework, ability to Managed Extensions for C++ executables, and non-locking behavior. It appears that Introspection is designed for applications and tools that perform large-scale reflecting on an assembly (perhaps reading all of the metadata into memory). In such cases, reflection would need to execute quickly for good reason. So, it would not probably not provide a performance improvement for simple uses of reflection in a standard app. One drawback is the SDK for the Introspection Engine has not been documented by the FXCop team. I suggest that developers who have already developed the custom rules using Microsoft.Tools.FxCop.Sdk.Reflection migrate your code to the Introspection Engine SDK and I believe the FXCop team is slowly changing there existing rules to leverage the advantages of the Introspection Engine SDK.

Now I will demonstrate how to write custom rules using the Introspection Engine SDK. The following is the sample code.

MyCustRules.cs

using System;
using Microsoft.Cci;
using Microsoft.Tools.FxCop.Sdk;
using Microsoft.Tools.FxCop.Sdk.Introspection;
#endregion
namespace
FxCop.MyCustRules
{
//Provides the base class for all introspection rules.
//The BaseIntrospectionRule class defines 15 different Check methods
//you can implement in your rules
[CLSCompliant(false)]
public abstract class MyBaseCustRule : BaseIntrospectionRule
{
//loading the rules.xml
// XML file name should be <namespace>.xml
//in this example its MyCustRules.xml
protected MyBaseCustRule(string name) : base(name, "FxCop.Rules.Rules", typeof
BaseRule).Assembly)
{
}
//overrides method of BaseIntrospectionRule.Check(TypeNode)
// to chekc the type of object
public override ProblemCollection Check(TypeNode type)
{
if (type == null)
return null;
switch (type.NodeType)
{
case NodeType.Class:
{
return Check((Class)type);
}
case NodeType.Interface:
{
return Check((Interface)type);
}
case NodeType.Struct:
{
return Check((Struct)type);
}
case NodeType.EnumNode:
{
return Check((EnumNode)type);
}
}
return base.Check(type);
}
// overrides method for BaseIntrospectionRule.Check(Module)
public override ProblemCollection Check(Module module)
{
if (module == null)
return null;
if (module.NodeType == NodeType.Assembly)
{
return Check((AssemblyNode)module);
}
return base.Check(module);
}
}
}

AvoidComplicated Method.cs

using System;
using System.Globalization;
using Microsoft.Cci;
using Microsoft.Tools.FxCop.Sdk;
using Microsoft.Tools.FxCop.Sdk.Introspection;
#endregion
namespace
FxCop.MyCustRules
{
//Checks for complicated methods.
// let's asume if the lines exceeeds 75 lines , called as complecated method
[CLSCompliant(
false)]
public class AvoidComplicatedMethods : MyBaseCustRule
// set the value as per your project specification
private const int MAXLINE= 75;
ublic AvoidComplicatedMethods() : base("AvoidComplicatedMethods")
{
}
//Overrides the check method and count the method lines
public override ProblemCollection Check(Member m)
{
Method method = m
as Method;
if (method == null)
return null;
if (method.Instructions == null)
return null;
string name = method.Name.Name;
if (name == "InitializeComponent")
return null;
int methodLineCounter = 0;
for (int i = 0; i < method.Instructions.Length; i++)
{
if (RuleHelper.IsMethodCall(method.Instructions[i]))
{
methodLineCounter++;
}
}
if (methodCallCount > MAXLINE)
{
// reporting the defects
//Problems.Add method helps to log the noncompliance code
Problems.Add(new Problem(GetResolution(RuleUtilities.Format(method), methodCallCount.ToString(CultureInfo.CurrentCulture), MAXLINE.ToString CultureInfo.CurrentCulture))));
}
return Problems;
}
}
}

MyCustRules.xml

<?xml version="1.0" encoding="utf-8" ?>
<
Rules FriendlyName="Custom Rules">
<
Rule TypeName="AvoidComplicatedMethods" Category="Custom" CheckId="Cust1001">
<
Name>Avoid complicated methods</Name>
<
Description>Methods that have many methodscalls or property are hard to maintain and therefore should be kept to a minimum.</Description>
<
Owner>Anand Kumar Rao</Owner>
<
Url></Url>
<
Resolution>'{0}' has {1} method calls. Refactor '{0}' so that it calls fewer than {2} methods.</Resolution>
<
Email>E-Mail ID = anandkumar2004@gmail.com</Email>
<
MessageLevel Certainty="95">Warning</MessageLevel>
<
FixCategories>NonBreaking</FixCategories>
</
Rule>
</
Rules>

To write the custom rules I have MyBaseCustRule derived from BaseIntrospectionRule. BaseIntrospectionRule has 15 different check methods to inspect the type of objects passed to the rule and in the constructor I am loading the XML file that contains a description of the rule and prompts the user asking if the code violates the rule.This XML file is very simple and you can extend that depending on your project's requirements. The AvoidComplicatedMethods class is derived from MyBaseCustRule and has implemented the Check method to read the number of lines present in each method of the class, checks that method should not exceed 75 lines. If it exceeds 75 lines then log the defect by calling the Problems.Add(....) method of the Introspection Engine.

Conclusion

I conclude this explanation by recommending the use of FXCop in your regular development to avoid bad coding and maintain the quality of the application. Visual Studio Team System (VSTS) has many enhancements primarily focusing on good coding standards and FXCop is builtin integrated with the Visual Studio IDE to check the code for compliance with Microsoft best practices. We will talk about in my future article.