YOUR FEEDBACK
The Cloud Wars - Is Guitar Hero a Cloud?
Roland Judas wrote: I am following the cloud discussions for some months n...

SYS-CON.TV
TOP MICROSOFT .NET LINKS


DNDJ Feature — Introducing C# Generics
Leverage code reuse without sacrificing type safety

Digg This!

Page 1 of 3   next page »

How often have you wanted to reuse some code you previously wrote but it didn't quite fit in your current project? Code reuse is an oft-touted benefit of modern object-oriented programming. With the advent of generic support in the C# language appearing in the .NET Framework 2.0 developers have new leverage for writing code that can be reused without compromising type safety.

About Type Safety
A key benefit to languages that support type checking is type safety. Type safety at build time and/or runtime prevents code from manipulating data of an incorrect type. As part of its type safe approach, C# detects type mismatch errors at build time in the compiler and at runtime in the Common Language Runtime (CLR). The following is a type mismatch error that C# will catch at build time:

    Object a = new Object();
    String b = a;

The second line will generate a compiler error because a plain Object can't be used as a String while maintaining type safety. Unfortunately, build-time type checking is ineffective if explicit casts are used. A cast lets the programmer circumvent the type checking at build time. For programming languages without runtime type checking this can result in invalid operations on data types having unpredictable consequences, such as manipulating a fragment of a String data type as if it were an int. C# provides type safety checks at runtime as well as build time. Here is a type mismatch error that won't be caught until the program is run:

    Object a = new Object();
String b = (String)a;

The program will build without errors. However, when running the program, it will generate an InvalidCastException on the second line because the Object referred to by 'a' can't be converted to the type String.

This type mismatch error is blatant but serves to remind us to avoid explicit casting since it negates the type safety provided at build time. Relegating these errors to program runtime incurs additional productivity cost (See "The Zen of Strong Typing" sidebar). In fact, now that we have the flavor of the type checking performed at build time, languages providing type safety features shouldn't lead us into situations that require us to turn off type safety by introducing such casts.

Reusing Code Without Generics
Evan, a programmer hired to write software for a local bakery, needs to manipulate strings. The implementation of a minimal collection is shown in Listing 1. The collection is a singly linked list called List1. Since Evan is only interested in storing String type data at this point, he builds the collection to fit the need to store String data. The bold text in Listing 1 shows the locations where the collection is specific to the type String.

Now Evan can use the collection as follows:

    List1 aList = new List1();
    aList.Add("a");
    aList.Add("b");
    for (String item = aList.Remove();
      item != List1.NO_ITEM;
      item = aList.Remove())
    {
      // Do something with item
    }

List1 is type safe, meaning it accepts and returns String types and this type safety is enforced at build time.

Eventually Evan has to track the products waiting for the oven, items in the oven, and goods under the display counter. This is an opportunity for reusing the previously programmed collection, List1. The problem is he now needs to collect BakeItems, not Strings. Evan could copy the source code to form a new collection by replacing String with BakeItem, but this approach has dire consequences. If an error is found later then both copies of the source code will have to be fixed. The baker has also indicated that Evan will also have to track waiting customers, inventory shipments, and other things. Writing separate collection code for each data type is clearly not desirable.

Evan decided to rewrite the collection with the most generally available type, Object. This results in a List2 class where the only difference is the replacement of all uses of the data type String with Object noted in bold text. Below is a fragment of List2.

    public class List2
    {
      public static Object NO_ITEM = default(Object);
      internal class ListNode
      {
public ListNode next = null;
public Object obj = NO_ITEM;
      }
      // ...

      public virtual void Add(Object obj)
      // ...

      public virtual Object Remove()
      // ...

Deprecating List1 in favor of List2 requires refactoring the earlier string collecting code.

    List2 aList = new List2();
    aList.Add("a");
    aList.Add("b");
    for (Object item = aList.Remove();
      item != List2.NO_ITEM;
      item = aList.Remove())
    {
      String theValue = (String)item;
      // Do something with theValue
    }

The advantage of this rewrite is that we can use List2 for any type of thing we want to collect. For primitive types, C# will perform a conversion to an appropriate object in a process called boxing. This lets us transparently handle primitive types as if they were objects. Therefore, we could use List2 with int as follows:

    aList.Add(1);
    aList.Add(2);
    for (Object item = aList.Remove();
      item != List2.NO_ITEM;
      item = aList.Remove())
    {
      int theValue = (int)item;
      // Do something with theValue
   }

For Evan, List2 seems well prepared for String, int, BakeItem, Customer, or anything else he might need. However, note that a cast is now necessary to convert from the most general type, Object, to the actual type, String or int in the code fragments. Recall that explicit casting is just the situation we want to avoid so we don't negate the type checking done at build time. For instance, during the development effort, Evan accidentally added an instance of a data type called BakeItem to a List2 collection meant only to contain Customer elements. The error will appear as an InvalidCastException at runtime, with no indication of problems at build time.

This weakens the original intent of having multiple different homogenous collections in a way that allows any individual collection to accept unintended data types. Even with the explicit casts that negate build time type checking, this approach to reusing code is superior to the alternative of writing code for a multitude of type-specific collections. This code reuse versus type safety tension was a problematic state of affairs with C# 1.1. With the addition of generics to C# 2.0 there is now a better solution to hand.



Page 1 of 3   next page »

About Robert R. Hauser
Robert R. Hauser has a masters degree in computer science specializing in Artificial Intelligence with more than 15 years of development experience in C, C++, C#, and Java, building software for networking, filesystems, middleware, and natural language processing. He works at Recursion Software, which is focused on providing a next generation application platform for .NET and Java.

MICROSOFT .NET LATEST STORIES
Gizmox Brings Microsoft Silverlight to Enterprises
Gizmox announced the release of a fully functional beta version of its Visual WebGui (VWG) with support for Microsoft Silverlight. For the first time, VWG enables Silverlight for enterprise applications by providing a RAD like Windows Forms development experience with drag & drop desig
Virtualization, Microsoft, Yahoo & Google
Citrix has tapped its VP of channels and emerging product sales Al Monserrat to replace its departing sales chief John Burris, who, as previously reported, is going to Sourcefire as CEO. A couple of years ago Monserrat was responsible for Citrix' North American sales. Meanwhile, Citrix
Microsoft's Silverlight Widgetry Sued for Patent Infringement
Microsoft and its cross-platform, Flash-rivaling, RIA-building Silverlight plug-in are being sued in San Francisco for patent infringement by a no-profile Massachusetts outfit called Gotuit Media Corporation. The thin seven-page suit and its venue comes compliments of California lawyer
Microsoft Disappoints, Ditto Google
Microsoft earned $4.3 billion on revenues of $15.84 billion, up 18%, in its fourth fiscal quarter in June, making it a $60 billion company - compliments of emerging markets and demand for Windows Server 2008. It had better-than-expected Vista sales this time through, up to $4.37 billio
Adobe's Kevin Lynch and Microsoft's Scott Guthrie to Keynote AJAX World RIA Conference & Expo
Two of the biggest launches in Rich Internet Application history took place in 2007/2008 when Adobe launched AIR 1.0 in February '08 and Microsoft launched Silverlight (September '07). At the 6th International AJAXWorld RIA Conference & Expo in October SYS-CON Events is delighted to be
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS
SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021

SYS-CON FEATURED WHITEPAPERS

MOST READ THIS WEEK
Working at Google vs. Working at Microsoft
And Now the Begging
JetBrains Releases ReSharper 4.0
Microsoft Kinda Moves Offline
ADS BY GOOGLE
BREAKING NEWS FROM THE WIRES
comScore Releases June 2008 U.S. Search Engine Rankings
comScore, Inc. , a leader in measuring the digital world, today released its monthly comScore