C# Tips and Tricks

Welcome to this installment of the .NET Nuts & Bolts column. As the title indicates, this article will be about C# tips and tricks. I’ll cover some of the C# 3.0 language features, explore productivity gains with the Visual Studio 2008 C# IDE, and mention a couple of handy Visual Studio plug-ins that may be of interest. This deviates from the traditional articles I’ve presented in the .NET Nuts & Bolts series and will hopefully provide some value in its own way.

C# 3.0 Background

C# 3.0 was released as a part of the Microsoft .NET 3.5 Framework. The main purpose was to provide a foundation for Language INtegrated Query (LINQ) to provide unified data access capability. Each enhancement also can be used on its own. Here is a list of the features you’ll cover and learn some related tips:

  • Automatically implemented properties
  • Using Keyword
  • Object and collection intitializers
  • Local type inference
  • Extension methods

Automatically Implemented Properties

Automatically implemented properties offer a concise syntax for implementing property accessors that get and set a private field. They create a field backed property without requiring you to actually create a field. The compiler automatically generates it for you at compile time. They can be used only for simple get and set of properties because there is no body and no field. No property body means no breakpoints or validation logic can be used. No field means no default value. Typing “prop [tab][tab]” is the Visual Studio code snippet for producing an automatically implemented property. This can make your code much more concise. A classic example of a field back property might look something like the code below.

private int myProperty = 0;
public int MyProperty
{
   get { return this.myProperty; }
   set { this.myProperty = value; }
}

A simpler example that uses automatically implemented properties for the same field is below.

public int MyProperty
{
   get; set;
}

However, it is important not to be too lazy and use this haphazardly. Examine the code below where you define a Customer class. Take note of the CustomerKey property that is defined. Typically, such a key field is a readonly item that is set once and doesn’t change. When taking a shortcut using automatically implemented properties, it allows for undesired behavior with the code.

class Customer
{
   public string CustomerKey { get; set; }
   public string ContactName { get; set; }
   public string City { get; set; }
}

You might try refactoring the code to have a private set and use a constructor to control the value. Although this does protect the field from the outside, it could still be altered internally to the class.

class Customer
{
   public Customer(string customerKey)
   {
      CustomerKey = customerKey;
   }

   public string CustomerKey { get; private set; }
   public string ContactName { get; set; }
   public string City { get; set; }
}

In reality, an automatically implemented property probably isn’t appropriate for the CustomerKey property and the code should look like the example below. The class in question in this example is pretty simple, but it illustrates the point that the automatically implemented properties should be applied liberally, but with caution.

class Customer
{
   public Customer(string customerKey)
   {
      this.CustomerKey = customerKey;
   }
   private readonly string customerKey;
   public string CustomerKey
   {
      get return this.customerKey;
   }

   public string ContactName { get; set; }
   public string City { get; set; }
}

using Keyword

There is a prior article in the .NET Nuts & Bolts series that is dedicated solely to the using keyword. Even though this isn’t necessarily new, it is worth mentioning and at least pointing to that article for more detail. The main benefit is that it can be used to implement try … finally behavior and offers an automatic cleanup of disposable types. There is a lot of value to be had by implementing this in your code whenever objects such as DataReader are used to ensure that connections will be properly disposed when complete.

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

Local Type Inference

Local type inference was also the subject of another prior .NET Nuts & Bolts article, but again is worth mentioning here as it is very handy to have a solid understanding. You define variables with the var keyword and the compiler will figure out the type for you at compile time and replace it. It is great for results from query expressions as show in the example below. It may appear that it is untyped or even give the impression it is a variant. It is not. It is a strongly typed object whose type is set at compile time.

var i = 5;
int i = 5;

string[] words = { "cherry", "apple", "blueberry" };

var sortedWords =
   from w in words
   orderby w
   select w;

Object and Collection Initializers

Initializers introduce a concise syntax that combines object creation and initialization in a single step. It even allows for parentheses to be optional for paramaterless constructors as you’ll see in the first line of the example below.

Point p = new Point { X=3, Y=99 };

Student myStudent = new Student() {
   Name   = "John Doe",
   Class  = "Senior",
   School = "Carmel" };

This functionality is great for demos where you are building collections of objects to do things like LINQ queries against. However, I caution you to consider real life initialization of large sets of data and whether code over a database is the proper place to store such information.

Initializers work very well with constructors. The example below shows an instance where a parameterized constructor is called along with remaining properties initialized. The constructor should commonly take all of the parameters so it isn’t an ideal setup, but it illustrates the point well.

class Customer
{
   public Customer(string customerKey) { ... }
   public string CustomerKey { get { ... } }
   public string ContactName { get; set; }
   public string City { get; set; }
}

var c = new Customer("MARKS"){
   ContactName = "Mark Strawmyer",
   City = "Indianapolis"
}

More by Author

Must Read