C# Programming Tips and Tricks

Introduction

Welcome to this installment of the .NET Nuts & Bolts column! When it comes to tips and tricks there are many items that can be considered. For this article we’ll briefly recap the C# 4.0 language features, cover some tips, tricks, and reminders, and touch on a couple of useful tools.

C# 4.0 Overview

C# 4.0 contains four primary areas of emphasis.


  • Dynamically typed objects

  • Optional and named parameters

  • Improved COM interoperability

  • Co- and contra-variance

The last .NET Nuts and Bolts article covered named and optional parameters and covered how it is responsible for some of the improved COM interoperability when interacting with DLLs such as the Office integration components. While named and optional parameters are available in C# programming now, it is important to establish ground rules for responsible use. The following table outlines considerations for when to use each.


<TABLE ALIGN=”center” BORDER=”0″ CELLSPACING=”0″ CELLPADDING=”0″ WIDTH=”100%”>
 <TR>
   <TD VALIGN=”top”>
<P><B>When to consider overloading:</B></p>
<UL>
 <LI>When defaults are not compile-time constants</LI>
 <LI>When alternatives specify different types</LI>
</UL>
   </TD>
   <TD valign=”top”>
<P><B>When to consider optional parameters:</B></P>
<UL>
 <LI>When you only need to specify default values for the optionals, especially if there are a number of optionals</LI>
</UL>
   </TD>
 </TR>
</TABLE>

Extension Methods

Extension methods allow you to add new functionality on existing types. This ability even includes the ability to add new functionality to sealed classes. They are declared like static methods and called like instance methods. They are scoped by using clauses and are valid for interfaces and constructed types. The following code example demonstrates adding two methods to the decimal type from the .NET Framework.


static class ExtensionSample
{
public static decimal Triple( this decimal d ) { return d*3; }
public static decimal Half( this decimal d ) { return d / 2; }
}

decimal y = 14M;
y = y.Triple().Half();


When building extension methods within your code base it is recommended to consider a separate namespace to allow them to be optional. It is also best you not be mean to others by applying to all objects by extending object. The following sample demonstrates what not to do as it alters the default behavior of all classes. Normally accessing a property or method on an object that is null a NullReferenceException would be generated. The extension method below would add a .IsNull() method that would alter that behavior, which then makes your code behave different from the default behavior expected from the .NET Framework. The following sample code demonstrates what not to do:


namespace System
{
 public static class MyExtensions
 {
   public static bool IsNull(this object o) {
     return o == null;
   }
 }
}

while (!myObject.IsNull()) { … }


Obsolete Code

If you’ve been using the .NET Framework for a number of years chances are you’ve seen the Framework versions advance and seen instances where some of the .NET Framework classes such as prior Configuration classes have gone obsolete and you’ve received warnings from the compiler about it to make you aware. You may have wondered how to do that same thing with your own code. There is an Obsolete attribute that you can use to decorate your own classes and methods to indicate they are being phased out as well. If you’re working independently of others, then chances are you won’t need it. However, in working with a project team where you may have implemented a framework, helper classes or other conventions, it can be very helpful to use the Obsolete attribute to flag dead code that won’t be used going forward. This allows them to be migrated over time rather than just deleting from your code. This is very handy as you refactor code to communicate through the compiler that a particular item is obsolete. By default the items are served up as warnings, but an optional flag can indicate if they should be treated as warnings. It is worthwhile to have that setting be a configuration value so that you can enable or disable it across the board.


// Include message for compiler to present
[Obsolete(“This class is dead.  It has been replaced by MyClass3.”)]
class MyClass1
{
// …
}

// Include message and generate a compiler error
[Obsolete(“This class is dead.  It has been replaced by MyClass4.  “), true]
class MyClass2
{
// …
}


Garbage Collection

If you are programming in .NET 3.5 or before you can force garbage collection through GC.Collect(), but it is heavily advised that you do not use it unless you really know what you are doing. It is very likely you’ll outguess the garbage collection system and do more harm than good. With the release of the .NET Framework 4.0 there are new garbage collection options and ways to control the behavior, which does make it more feasible to trigger and control. (Note: this will likely be a future article).

Using Keyword

The using keyword has multiple uses. One lesser known is it can be used to provide automatic cleanup of disposable types. The compiler translates it in to try…finally behavior. I highly recommend using it whenever using IDataReader or the LINQ to Entity data context to retrieve data from the database. The following sample code demonstrates a simple implementation where a DataReader is wrapped in a using statement to ensure it is disposed when its use is out of scope.


using (IDataReader reader =
provider.ExecuteReader(dataCmd))
{
// …
}

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read