Monday, January 18, 2010

Episode 64

In this interview, author and developer Bill Wagner discusses the dynamic features in the upcoming C# 4.0.

Monday, January 18, 2010 10:03:20 AM (Eastern Standard Time, UTC-05:00)
 Sunday, September 13, 2009

Back To Basics

The yield return and yield break keywords are shortcuts introduced in C# 3.0. They are designed to assist you in a method that returns IEnumerable <T>.
Often such methods consist of the following steps

  1. Create an empty IEnumerable set.
  2. Loop through some data (via a while, foreach or other construct)
  3. Add to the set within your loop.
  4. Exit the loop when some limit is reached.
  5. Return the set.

A sample of such code is shown below.

public IEnumerable<Int32> GetOddNumbers_Old(Int32 maxNumber)
{
    List<Int32> oddSet = new List<Int32>();
    int num = 0;
    while (true)
    {
        System.Threading.Thread.Sleep(1000);
        num++;
        if (num % 2 == 1)
        {
            oddSet.Add (num);
        }
        if (num >= maxNumber)
        {
            break;
        }
    }

    return oddSet;
}

The new yield keywords allow you to shorten your code to only the following steps

  1. Loop through some data
  2. yield return within the loop
  3. yield break if a limit is reached before the loop is complete

That’s it. There is no need to explicitly create or return your IEnumerable set.

The yield return statement appends a value to the IEnumerable set. The yield break statement exits any looping construct to prevent more items being added to the return set. If you omit yield break, the loop exits as it normally would.

The difference between using the yield return and simply returning a set is subtle. Returning a set at the end of the method returns the entire set at once. The client must wait until the method is complete before it can use any values in the return set. Each time the yield return statement executes, the client has access to another element in the set. Essentially the set trickles back a little at a time. This can provide a gain in performance or perceived performance if you have a large set to return.

Here is a sample that returns the same results as above, using yield return and yield break.

public IEnumerable<Int32> GetOddNumbers_Yield(Int32 maxNumber)
{
    int num = 0;
    while (true)
    {
System.Threading.Thread.Sleep(1000); num++; if (num % 2 == 1) { yield return num; } if (num >= maxNumber) { yield break; } } }

If we call the two methods above, we will get the same results but they will return in slightly different ways. I added the System.Threading.Thread.Sleep(1000); line to help demonstrate this. That line simply pauses execution for 1 second each time the loop executes.

Assume the above two methods are in a class named MyMethods.  The following code will call each.

Console.WriteLine("Get Odd Numbers using old way:");
MyMethods mm = new MyMethods();
IEnumerable<Int32> oddNumbers2 = mm.GetOddNumbers_Old(11);
foreach (Int32 n in oddNumbers2)
{
    Console.WriteLine(n);
}

Console.WriteLine();


Console.WriteLine("Get Odd Numbers using new YIELD keyword:");
IEnumerable<Int32> oddNumbers1 = mm.GetOddNumbers_Old(11);
foreach (Int32 n in oddNumbers1)
{
    Console.WriteLine(n);
}

Console.ReadLine();

The above code produces the following output

Get Odd Numbers using old way:
1
3
5
7
9
11

Get Odd Numbers using new YIELD keyword:
1
3
5
7
9
11

Notice that both methods return the same data. However, if you watch the code as it runs, you will notice the first method waits 12 seconds, then immediately outputs all odd numbers; while the second method outputs a number every 2 seconds. Each method returns the same values and each takes the same amount of time, but the second method uses yield return, so the client is able to output a bit of data each time a yield return executes.

There are a few restrictions to using the yield keywords

  • These keywords cannot appear in blocks marked "unsafe"
  • These keywords cannot appear in a method with ref or out parameters
  • The yield return statement is not allowed inside a try-catch block, although it may be located inside a try-finally block.
  • A yield break statement may not be located inside a finally block.

You can download this sample code at DemoYield.zip (45.06 KB)


Mike Wood contributed to this article.

Sunday, September 13, 2009 8:44:07 AM (Eastern Standard Time, UTC-05:00)
 Saturday, September 12, 2009

Back To Basics

Prior to C# 3.0, we had two common ways to initialize the public properties of an object.

  1. We could use the default constructor to instantiate the object; then, use a separate line of code to assign a value to each property. (Listing 1)
  2. We could create a constructor that accepts an argument for each property; and write code in this constructor to assign to each public property the value passed in for each corresponding argument. (Listing 2 and Listing 3)

The first method is quite verbose and requires a lot of code for complex objects.

Listing 1:

Customer cust1 = new Customer();
cust1.CustomerID = 1;
cust1.FirstName = "George";
cust1.LastName = "Washington";
cust1.StreetAddress = "111 A St";
cust1.City = "Aville";
cust1.State = "MI";
cust1.ZipCode = "10001";

Listing 2:

class Customer
{
    public Int32 CustomerID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string StreetAddress { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }

    public Customer
        (
        Int32 customerID,
        string firstName,
        string lastName,
        string streetAddress,
        string city,
        string state,
        string zipCode
        )
    {
        CustomerID = customerID;
        FirstName = firstName;
        LastName = lastName;
        StreetAddress = streetAddress;
        City = city;
        State = state;
        ZipCode = zipCode;
    }
}

Listing 3:

Customer cust2 = new Customer
    (
    2,
    "John",
    "Adams",
    "222 B Ave",
    "Beetown",
    "MI",
    "20002"
    );

The second method is more elegant, but assumes we always want to initialize every single public property at object instantiation. Of course, we could create multiple constructors to accommodate times when we only want to initialize certain variables but this can get complex in a hurry when our class has a lot of public properties.

Beginning with C# 3.0, we can now initialize public properties in the same line of that instantiates an object; and we can do so without creating a new constructor. We use object initializers to do this. 

Using object initializers we can still use the default constructor (or any public constructor we want); but we can set public properties by appending the property assignments within a set of curly braces at the end of the object initializer, as shown in listing 4.

Listing 4:

Customer cust4 = new Customer() 
            {   CustomerID = 4, 
                FirstName = "James", 
                LastName = "Monroe" 
            };

This new C# feature is known as object initializers. This method gives us a great deal of flexibility. At the time we instantiate an object, we can decide which properties to initialize. And we can do so without creating a plethora of constructors for the object or return to the verbose way of assigning property values after an object's instantiation.

Object initializers are most useful when you instantiate a class in many different places throughtout an application.

Download this code to view and run a simple application that uses object initializers DemoObjectInitializers.zip (24.92 KB)
Saturday, September 12, 2009 8:10:03 AM (Eastern Standard Time, UTC-05:00)
 Friday, September 11, 2009

Back To Basics

Automatic properties were introduced in C# 3.0 as a convenience to developers.

C# and Visual Basic .Net provide two ways for a class to maintain state: Fields and Properties.

A field is a simply a public variable defined inside a class, such as in the following example

public string foo;

A property looks much like a field to the outside world, but exposes two methods – a “getter” to allow you to retrieve the value of the property and a “setter” to allow you to assign a value to the property. The following sample demonstrates how to implement a read-write property in C#.

private string _firstName;
public string FirstName
{
    get
    {
        return _firstName;
    }
    set
    {
        _firstName = value;
    }
}

This is a common use of property getters and setters – to assign and retrieve the value from a private variable. Because there is no extra logic in these methods, similar functionality could be achieved using a field, but I prefer to use properties in case I decide later to add some validations or calculations to the setter or getter. Making a change like that to a property will not break the class signature, forcing a recompile of dependent objects.

But this is a lot of typing for such simple functionality. So much in fact that Visual Studio 2005 provided a right-click accelerator to type much of it for you.

Beginning with C# 3.0, automatic properties provide a shorthand notation for this functionality.  Simply provide the scope, the type and the name of the property, followed by “{get; set; }” and the framework will automatically create a private variable for you and provide code to save and retrieve to/from that private variable. This is all done behind the scenes for us so we don’t need to write any of this code.  Below is a sample of the code we need to write for a public property.

public string FirstName { get; set; }

To make a property read-only, simply omit the "set" keyword. To make it write-only, omit the "get" keyword. Below is syntax for the same property if I wanted it to be read-only.

public string FirstName { get; }

The only disadvantage to automatic properties is that the rest of the code in our class no longer has access to the private variables create by the framework. Even from within the same class, we must go through the public property in order to get or set the private variable.

This is a small price to pay for the amount of code we are saving.

Automatic properties not only require less typing, they are far easier to read when your class has a bunch of properties. Which of the following easier to read?

public string FirstName { get; set; }
public string LastName { get; set; }
public string StreetAddress { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }

or

private string _firstName;
public string FirstName
{
    get
    {
        return _firstName;
    }
    set
    {
        _firstName = value;
    }
}

private string _lastName;
public string LastName
{
    get
    {
        return _lastName;
    }
    set
    {
        _lastName = value;
    }
}

private string _streetAddress;
public string StreetAddress
{
    get
    {
        return _streetAddress;
    }
    set
    {
        _streetAddress = value;
    }
}

private string _city;
public string City
{
    get
    {
        return _city;
    }
    set
    {
        _city = value;
    }
}

private string _state;
public string State
{
    get
    {
        return _state;
    }
    set
    {
        _state = value;
    }
}

private string _zip;
public string Zip
{
    get
    {
        return _zip;
    }
    set
    {
        _zip = value;
    }
}

I think you’ll agree that it is far easier to read and understand the more terse syntax of the first example.  And code that is easier to understand is easier to maintain.

Because both syntax versions compile to the same Intermediate Language, I recommend always using the newer Automatic Properties syntax when you create properties that do nothing more than save and retrieve state.

Download the following sample code to see automatic properties in action: DemoAutomaticProperties.zip (26.83 KB)
Friday, September 11, 2009 7:17:17 AM (Eastern Standard Time, UTC-05:00)
 Friday, September 04, 2009

Back To Basics

Extensions methods are a new feature of C# 3.0 and they are easier to use than they first appear.

An extension method is a method that is external to an existing class but appears as if it were a method on that class.

The rules for creating an extension method are simple.

  1. Create a static method
  2. The first parameter of the static method should be the type of the class you wish to extend
  3. Precede the parameter type of this first parameter with the "this" keyword.
  4. Call the method as if it were a method of the class. Omit the first parameter.

An example should clarify this. Assume we have a class Customer with properties FirstName and LastName as shown below

    public class Customer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

We can create a new static class MyExtensions with a static method GetFullName that returns the formatted first and last name of the customer. We do so with the following code

   public static class MyExtensions
    {
        public static string GetFullName(this Customer cust)
        {
            string custName = cust.FirstName + " " + cust.LastName;
            return custName.Trim();
        }
    }

Notice the parameter with the "this" keyword. That parameter format tells the compiler that this is an extension method and that it should extend the Customer class. As long as MyExtensions is in the same namespace or in a namespace available to our code (via the "using" statement), we can call this new extension method with the following code

Customer cust 
    = new Customer 
         { FirstName = "David", 
           LastName = "Giard" 
         };
string fName = cust.GetFullName();
Console.WriteLine(fName);

The code above outputs:

   David Giard

As you can see in the above code, it looks as if the GetFullName method is part of the Customer class.

We can add parameters to our extension methods as we would to any other method. The first parameter (with the “this” keyword) is always used to specify the class we are extending. All other parameters act just like normal parameters. The following extension method accepts a parameter “salutation”.

public static string GetGreeting(this Customer cust, string salutation)
{
    string custName = cust.FirstName + " " + cust.LastName;
    custName = custName.Trim();
    return salutation + “ “ + custName + ":"; 
}

Although the extension method has two parameters, we only need to pass the second parameter when calling it, as shown

Customer cust = new Customer { FirstName = "David", LastName = "Giard" };
string greeting = cust.GetGreeting("Dear");
Console.WriteLine(greeting);

The code above outputs:

   Dear David Giard:

In our examples, we were adding extension methods to a class that we just created. Of course, in this case, it would have been simpler to just modify the original class.  But extension methods are more useful if you are working with someone else’s class and modifying the source code is not an option. Extension methods often offer a simpler solution than inheriting from an existing class.

The real power of extension methods comes from the fact that you can even add methods to sealed classes. It is difficult to add functionality to a sealed class because we cannot inherit from it. Change the Customer class to sealed and re-run the code to prove that it still works.

public sealed class Customer

Here is the all code in the above sample

using System;

namespace TestExtensionMethods
{
    class Program
    {
        static void Main(string[] args)
        {
            Customer cust = new Customer { FirstName = "David", LastName = "Giard" };

            string fn = cust.GetFullName();
            Console.WriteLine(fn);

            string greeting = cust.GetGreeting("Dear");
            Console.WriteLine(greeting);

            Console.ReadLine();

        }
    }


    public sealed class Customer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }


    public static class MyExtensions
    {
        public static string GetFullName(this Customer cust)
        {
            string n = cust.FirstName + " " + cust.LastName;
            return n.Trim();
        }

        public static string GetGreeting(this Customer cust, string salutation)
        {
            string custName = cust.FirstName + " " + cust.LastName;
            custName = custName.Trim();
            return salutation + " " + custName + ":"; 
        }
    }

}

You can download the sample code at TestExtensionMethods.zip (24.26 KB)

 

Friday, September 04, 2009 8:52:43 PM (Eastern Standard Time, UTC-05:00)