Channels ▼
RSS

.NET

Inside Visual Studio 2008

Source Code Accompanies This Article. Download It Now.


Richer Languages Beyond the Sugar

Programming languages are not immutable. Especially when they're tightly coupled to a runtime environment such as the CLR, they progress as the underlying machinery is refined and enhanced. For example, the .NET Framework 2.0 supplied a C# compiler with additional features compared to the compiler for the .NET Framework 1.x. In Visual Studio 2008 and with .NET 3.5 onboard, you can use a significantly richer C# and Visual Basic .NET languages.

Both languages now incorporate features that enable functional programming and add specific keywords for Language Integrated Queries (LINQ).

Extension methods are a way to extend the otherwise hard-coded contract of a class by adding new methods programmatically without creating a derived or partial class. The idea behind extension methods is bringing the flexibility of duck-typing to a strongly-typed and compiled environment such as the CLR. In practice, you may use extension methods whenever you feel that a given class you're using lacks a helpful method. If you have no access to the source code of this class, in Visual Studio 2008 you define an extension. Extension methods can be defined for any class, including native classes of .NET. Listing One shows how to extend the System.String class with a few methods such as IsDate, IsInt32, and ToDate.

namespace Samples
{
    public static class StringExtensions
    {
        public static bool IsInt32(this string content)
        {
            int number;
            bool result = Int32.TryParse(content, out number);
            return result;
        }
        public static bool IsDate(this string content)
        {
            DateTime date;
            bool result = DateTime.TryParse(content, out date);
            return result;
        }
        public static DateTime ToDate(this string content)
        {
            DateTime date;
            bool result = DateTime.TryParse(content, out date);
            if (result)
                return date;
            else
                return DateTime.MinValue;
        }
        public static int ToInt32(this string content)
        {
            int number;
            bool result = Int32.TryParse(content, out number);
            if (result)
                return number;
            else
                return Int32.MinValue;
        }
    }
}
Listing One

An extension method is defined as a static method on a static class. The binding between the method (say, IsInt32) and type (say, System.String) is established through the this keyword in the method's prototype:

     
public static bool IsInt32 (this string content)


The type that follows the this keyword is treated as the type to extend. Figure 3 shows IntelliSense in action on the extended System.String type.

[Click image to view at full size]

Figure 3: IntelliSense shows dynamic extensions to the String type.

The following code illustrates how you can use these new methods in your code:


void btnDate_Click(object sender, EventArgs e) {
  string content = textBox1.Text;
  if (content.IsDate()) {
    DateTime date = content.ToDate();
    label2.Text = String.Format("Next day is {0}", 
       date.AddDays(1).ToString("dd MMMM yyyy"));
  }
  else
      label2.Text = "Not a valid date.";
} 


Extension methods are checked at compile-time and can be applied also to any parent class or interface in .NET. (Extension methods could be used to obtain a feature that looks similar to mix-ins. Overall, a mix-in is a sort of interface with implemented methods. A class that implements a mix-in includes—but not inherits—all the members on the mix-in's interface. Currently, C# and Visual Basic .NET don't natively support mix-ins, even though instructing the compilers to produce the code for it didn't appear to be a huge effort. With extension methods, you can simulate mix-ins in the latest C# and Visual Basic .NET.)

The var keyword is another interesting new entry. Used to qualify a variable, it doesn't indicate a late-bound reference. Instead, it merely indicates that you don't know the type of the variable at the time of writing. However, the type won't be determined at runtime (late-binding), but the compiler infers the type from the expression assigned to the var variable. For this reason, an initial value assignment is required to avoid a compiler error. When var is used, a strongly typed reference is always generated.

The var keyword enables another cool C# feature—the anonymous type. This is an unnamed type that you define using the same object initializer syntax mentioned earlier:


var person = new { 
    FirstName="Nancy",
    LastName="Davolio", 
    Age=28
};


For the CLR, anonymous and named types are exactly the same entity. Anonymous types can be used in a variety of scenarios, but have been introduced primarily to support LINQ queries.

The same can be said for lambda expressions. Lambda expressions are used as a convenient way to create delegates, especially (but not uniquely) in LINQ. In .NET, a delegate is an object-oriented wrapper for a function pointer and points to an existing and named function in a class. In .NET 2.0, managed languages offered new, powerful construct—anonymous methods. Basically, you have an explicit code snippet defined inline and used as an unnamed method of some class. Lambda expressions are a further refinement of the idea of an anonymous method, just less verbose and niftier.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video