Saturday, December 22, 2007

Nutcracker

Welcome back my 'nog-froth mustachioed friends! I've returned with another helping of Refactor! Pro goodness for Visual Studio 2008. One scrooge commented that the last present was a little weak, so I've decided to give a bigger gift this time. However, I will be saving some of my bestest presents for the very end.

So, sit back, relax and take out your ear plugs as I serenade you with my third verse.

"On the third day of X-mas my true love (DevExpress) gave to me..."

Name Anonymous Type

Of all the new features in C# 3.0 and Visual Basic 9, Anonymous Types is one of the most convenient. This feature allows the user to create new objects "on the fly," without providing type definitions for them. For example:

var person = new { Name = "St. Nick", Age = "Really Old" };
Console.WriteLine(person.Name);

When the C# compiler encounters the code above, it generates a new type with two string properties: Name and Age.

This powerful new feature is not without limitations. Because anonymous types have no accessible type name (they're anonymous - duh!), they can only be referenced by variables that are implicitly-typed. This becomes very frustrating when using anonymous types in other natural ways.

public static ??? CreatePerson()
{
  return new { Name = "St. Nick", Age = "Really Old" };
}

What should I fill in for ??? in the code above? One possibility is to use object. However, if I do that, how do I access the properties from client code? Reflection? An awkward casting helper?

Recently, this very problem was hashed out on the MSDN forums. The general consensus was, when you want to expose an anonymous type in an API (e.g. return an anonymous type from a method), swap it out for a defined type. However, defining a new type that matches an anonymous type is cumbersome. Thankfully, Refactor! Pro can step in and do this work for you. When the Name Anonymous Type refactoring is applied to the anonymous type above, the following class is generated:

[DebuggerDisplay("\\{ Name = {Name}, Age = {Age} \\}")]
public sealed class Person: IEquatable<Person>
{
  private readonly string m_Name;
  private readonly string m_Age;

  public Person(string name, string age)
  {
    m_Name = name;
    m_Age = age;
  }

  public override bool Equals(object obj)
  {
    if (obj is Person)
      return Equals((Person)obj);
    return false;
  }
  public bool Equals(Person obj)
  {
    if (!EqualityComparer<string>.Default.Equals(m_Name, obj.m_Name))
      return false;
    if (!EqualityComparer<string>.Default.Equals(m_Age, obj.m_Age))
      return false;
    return true;
  }
  public override int GetHashCode()
  {
    int hash = 0;
    hash ^= EqualityComparer<string>.Default.GetHashCode(m_Name);
    hash ^= EqualityComparer<string>.Default.GetHashCode(m_Age);
    return hash;
  }
  public override string ToString()
  {
    return String.Format("{{ Name = {0}, Age = {1} }}", m_Name, m_Age);
  }

  public string Name
  {
    get
    {
      return m_Name;
    }
  }
  public string Age
  {
    get
    {
      return m_Age;
    }
  }
}

View Screencast of Name Anonymous Type in Action!

You might be thinking, "Wow! That's a lot of code! Is all of that really necessary?" The answer is, yes, all of that code is necessary to produce a type definition that is equivalent to the subtle features of an anonymous type. In C#, anonymous types are immutable so we must generate read-only fields and properties. In addition, the equality and identity of anonymous types are explicitly defined so they can be compared with one another. In other words, C# anonymous types have value-type semantics. The following code sample might clarify this:

var person1 = new
{
  Name = "Dustin Campbell",
  Age = "32"
};

var person2 = new
{
  Name = "Dustin Campbell",
  Age = "32"
};

var person3 = new
{
  Name = "Dustin's Trophy Wife",
  Age = "Undisclosed (but probably really, really young)"
};

Console.WriteLine(person1.Equals(person2));
Console.WriteLine(person2.Equals(person3));

Because of the value-type characteristics of anonymous types, the above code outputs the following to the console.

True
False

Of course, if Name Anonymous Type is applied, the same output is produced.

Traditionally, the Visual Basic team likes to make life hard for us, and anonymous types are no exception. Contrary to C#, the Visual Basic compiler generates mutable anonymous types. In addition, Visual Basic allows for partially-mutable anonymous types when the Key keyword is applied. (This is further proof that C# and Visual Basic have very different agendas and destinies.) Fortunately, Name Anonymous Type is intelligent enough to handle these differences.

Dim person = New With {.Name = "St. Nick", .Age = "Really Old"}

When applied to the above code, Name Anonymous Type generates a new Person class like so:

<DebuggerDisplay("\{ Name = {Name}, Age = {Age} \}")> _
Public NotInheritable Class Person
  Private m_Name As String
  Private m_Age As String

  Public Sub New(ByVal name As String, ByVal age As String)
    m_Name = name
    m_Age = age
  End Sub

  Public Overrides Function ToString() As String
    Return String.Format("{{ Name = {0}, Age = {1} }}", m_Name, m_Age)
  End Function

  Public Property Name() As String
    Get
      Return m_Name
    End Get
    Set(ByVal value As String)
      m_Name = value
    End Set
  End Property
  Public Property Age() As String
    Get
      Return m_Age
    End Get
    Set(ByVal value As String)
      m_Age = value
    End Set
  End Property
End Class

To be consistent with the reference-type semantics of Visual Basic anonymous types, Name Anonymous Type produces a mutable class. Gone are the overrides to Equals() and GetHashCode(). In addition, the properties are read-write. It's this sort of language independence that makes Refactor! Pro a choice tool for Visual Studio 2008 development.

And that wraps up another verse in my holiday sing-a-long! Remember that the features I am showing can be used right now. There's no need to wait for some forthcoming beta. You can use them today. Until next time...

posted on Saturday, December 22, 2007 11:35:00 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1]

kick it on DotNetKicks.com
 Friday, December 21, 2007

Fireplace

Season's greetings! Welcome back for another dose of Yuletide cheer! Yesterday, I sang to you about one way in which Refactor! Pro can be used to leverage the new features of C# 3.0 and Visual Basic 9 right now. Today, I'm back with another verse to warm your hearts this holiday season.

So, strike up the band! Rouse the drunken carolers! It's time to go a wassailing once more.

"On the second day of X-mas my true love (DevExpress) gave to me..."

Make Explicit

Like its sister refactoring, Make Explicit enables developers to manipulate implicitly-typed local variables. However, it performs the opposite operation as Make Implicit. It converts implicitly-typed local variables to explicit ones. In other words, Make Explicit will transform the following code:

var number = 42ul;

Like so:

ulong number = 42ul;

Make Explicit must do a great deal of work to determine the type of the expression that an implicitly-typed local variable is assigned to. Consider the following code (which I found lurking in some corner of the 'net):

using System;
using System.Linq;
using System.ServiceProcess;

namespace TwelveDaysOfXmas
{
  class MakeExplicit
  {
    static void DisplayServices()
    {
      var services = from service in ServiceController.GetServices()
                     where service.Status == ServiceControllerStatus.Running
                     orderby service.ServiceName ascending
                     select service;

      foreach (ServiceController aService in services)
      {
        Console.WriteLine(aService.ServiceName);
      }

      Console.ReadLine();
    }
  }
}

In order to determine the type of services, Make Explicit must have a full understanding of LINQ. First, it must transform the query expression into the appropriate extension methods and lambda expressions like so:

var services = ServiceController.GetServices()
                 .Where(service => service.Status == ServiceControllerStatus.Running)
                 .OrderBy(service => service.ServiceName)

Next, Make Explicit must be able to resolve the extension methods and infer the types of the lambda expressions. Once this is done, the type of the expression can finally be determined. That's an awful lot of work, but it's required to ensure that the type is inferred accurately. Fortunately, Make Explicit executes all of this with blazing speed and infers the correct type:

IOrderedEnumerable<ServiceController> services = from service in ServiceController.GetServices()
                                                 where service.Status == ServiceControllerStatus.Running
                                                 orderby service.ServiceName ascending
                                                 select service;

View Screencast of Make Explicit in Action! (#1)

If you have any doubt that Make Explicit is really doing this much work behind the scenes, try commenting out the orderby clause. Make Explicit will infer the correct type even after the query expression has changed:

IEnumerable<ServiceController> services = from service in ServiceController.GetServices()
                                          where service.Status == ServiceControllerStatus.Running
                                          //orderby service.ServiceName ascending
                                          select service;

View Screencast of Make Explicit in Action! (#2)

Finally, I should mention that Make Explicit works just as handily with Visual Basic.

Dim services = From service In ServiceController.GetServices() _
               Where service.Status = ServiceControllerStatus.Running _
               Order By service.ServiceName Ascending

In the above code, Make Explicit properly infers the type of services as IOrderedEnumerable<ServiceController>. Awesome.

One last closing thought: some of you might be thinking right now, "Why would I want to do this? Aren't implicitly-typed local variables better?" There are a few scenarios in which Make Explicit is useful:

  1. Specifying the type name sometimes makes code easier to read.
  2. It simplifies porting code backwards (e.g. to compile in an earlier version of Visual Studio).
  3. It can be helpful for learning and understanding code.

For these reasons, Make Explicit takes its rightful place among the refactorings that support Visual Studio 2008.

"And a partridge in a pear tree..."

And so concludes today's verse. It's time to settle back with a warm mug of spiked eggnog and kick up your feet. Join me tomorrow as we take a peek at another way in which Refactor! Pro brings the X-mas love.

posted on Friday, December 21, 2007 1:44:12 PM (Eastern Standard Time, UTC-05:00)  #    Comments [3]

kick it on DotNetKicks.com
 Thursday, December 20, 2007

Fireplace

Gentle readers, in the spirit of X-mas, I'd like to sing you a carol. This jolly tune (based on a popular old English carol) enumerates ways that Refactor! Pro can warm your installation of Visual Studio 2008 this holiday season. In contrast to some of our... ahem... <whisper>competition</whisper>, the features I'll be showing can be used today. In fact, most of these features have been shipping since Visual Studio 2008 was still a wee child known by its code name, Orcas.

But, hey, enough of my yammering! Stoke the fire and put on a kettle! Let the merry-making begin!

"On the first day of X-mas my true love (DevExpress) gave to me..."

Make Implicit

Visual Studio 2008 introduced a welcome addition to both the C# and Visual Basic languages: implicitly-typed local variables. While this feature is necessary to properly support another feature, anonymous types, it can also be used to enhance the readability of client code—especially when generic types are being used. Consider the following code:

private static Dictionary<string, Guid> BuildIdTable()
{
  Dictionary<string, Guid> map = new Dictionary<string, Guid>();

  // Fill map with entries...

  return map;
}

That sort of code can be a bit frustrating. Dictionary<TKey, TValue> is extremely powerful, but can be awkward to use. The developer is forced to fully declare the type name (which is often quite long) on both the left and right sides of the local variable declaration. Thankfully, an implicitly-typed local variable can alleviate this problem:

private static Dictionary<string, Guid> BuildIdTable()
{
  var map = new Dictionary<string, Guid>();

  // Fill map with entries...

  return map;
}

Now for the really good news: Refactor! Pro provides Make Implicit, a refactoring which easily converts explicitly-declared local variables to implicit ones. Check out the preview hint for Make Implicit:

View Screencast of Make Implicit in Action!

Of course, like most of our refactorings, Make Implicit works in Visual Basic as well.

Some critics might be thinking, "What's the point? It just deletes text and inserts a keyword! I could write a macro to do that!" Well, before those skeptics get too comfortable with their new macro, consider what Make Implicit must do with code like the following:

ulong number = 42;

If Make Implicit were simply to swap ulong for var, there would be a serious problem. Instead of ulong, the type of number would be inferred as int, changing the meaning of the code. To fix this problem, a minor adjustment is made to prevent shooting the code in its proverbial foot.

var number = 42ul;

So, throw your macro away! Let Make Implicit handle the edge cases intelligently.

Ho, ho, ho! That's quite a gift under the tree! Come back tomorrow when I continue my jaunty tune and look at another Visual Studio 2008-specific refactoring that is available to you today: Make Explicit.

posted on Thursday, December 20, 2007 1:31:39 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]

kick it on DotNetKicks.com
 Wednesday, December 19, 2007
Last night, I had the pleasure of presenting my Functional C# talk to the West Michigan .NET User Group. It was truly a joy. The group is sharp, attentive and engaging. In addition, their venue is very cool. WMNUG meets at the Watermark Country Club in Grand Rapids, MI, where they get gourmet pizzas delivered to them (no fast-food pizza for these guys!) and have access to a cash bar. Needless to say, the presentation became a bit more "spontaneous" as I consumed my fill of a wonderful brown ale. Thanks to my good friend Chris Woodruff for supplying me with the beer.

Speakers: If you're looking for a great place to present, this is it.

posted on Wednesday, December 19, 2007 3:05:16 PM (Eastern Standard Time, UTC-05:00)  #    Comments [2]

kick it on DotNetKicks.com
Launchy, my favorite utility for launching applications, received a much-needed update yesterday. In fact, I didn't realize just how badly the update was needed until I downloaded the new version.

Launchy in action

Check out the list of changes:

  • Launchy has been completely rewritten with QT
    • Your old plugins/skins will no longer work
    • Your old configuration will be wiped
  • A new look! New icons and skin thanks to Tyler Sticka
  • Much better skinning support
  • Options merged into a single, tabbed dialog
  • Skin selection now shows previews
  • Plugins much more configurable
  • Launchy can hide when it loses focus
  • Fade in/out effects
  • Customizable transparency
  • Optional shallow scan of directories
  • Unicode support for Firefox bookmarks
  • Vista support
  • It’s just better.

After running the new version for a short while, I can verify that the last item in that list is quite true. Launchy 2.0 really is just better. If you've been on the fence with regard to application launchers or (shudder!) don't use one at all, stop reaching for the mouse and take Launchy for a spin.

posted on Wednesday, December 19, 2007 9:32:36 AM (Eastern Standard Time, UTC-05:00)  #    Comments [3]

kick it on DotNetKicks.com
 Monday, December 10, 2007

Happy Birthday!

Bethany Anne Campbell was born on December 9, 2007 at 10:40 a.m. At 5 weeks early, Bethany was definitely a big surprise. However, it was pretty clear that she was ready to join us on the outside. Once we arrived at the hospital, it was only thirty minutes before Bethany was born. I suppose that means that she'll always be one or two steps ahead of us.

posted on Monday, December 10, 2007 6:58:50 AM (Eastern Standard Time, UTC-05:00)  #    Comments [17]

kick it on DotNetKicks.com
 Friday, November 23, 2007
Visual Studio 2008's multi-targeting support for compiling projects to different versions of the .NET Framework is very powerful. Multi-targeting is a compelling feature because it enables users to continue working on solutions that target .NET Framework 2.0 and 3.0 while upgrading to the latest and greatest IDE. What isn't obvious is that all projects, regardless of target, are compiled with the C# 3.0 compiler. That means users can employ many of the new C# 3.0 language features in legacy projects. The only language features that can't be used are those that require library support from .NET Framework 3.5, in essence, LINQ, Expression Trees and Extension Methods. Implicitly-typed local variables, lambda expressions, auto-implemented properties, object and collection initializers, and anonymous types are all fair game. It's sort of like having C# 3.0-lite or C# 2.5.

Interestingly, it has recently been discovered that even Extension Methods can be used in projects targeting .NET Framework 2.0 and 3.0. All that must be done to enable this support is to create a new System.Runtime.CompilerServices.ExtensionAttribute.

using System;

namespace System.Runtime.CompilerServices
{
  public class ExtensionAttribute: Attribute
  {
  }
}

This trick does have flaws. There are potential scoping issues that occur when an assembly containing a custom System.Runtime.CompilerServices.ExtensionAttribute is referenced by a project that targets .NET Framework 3.5. A compiler warning is generated stating that "the predefined type 'System.Runtime.CompilerServices.ExtensionAttribute' is defined in multiple assemblies in the global alias." However, this is only a minor irritation. In my tests, Extension Methods still worked properly despite the warning.

The ability to use C# 3.0 features in .NET Framework 2.0 or 3.0 projects is very powerful. It helps users get comfortable with the new syntax without having to upgrade projects to .NET Framework 3.5. Viva la C# 2.5!

posted on Friday, November 23, 2007 10:29:08 AM (Eastern Standard Time, UTC-05:00)  #    Comments [5]

kick it on DotNetKicks.com
 Tuesday, November 13, 2007
While exploring F#, I've grown increasingly impressed by the libraries that ship with it. One of the main purposes of the libraries is to provide underlying support for the language itself. In addition, they contain important modules and classes necessary for functional programming (e.g. immutable List and Map types). However, the most practical aspect of these libraries to me is the rich set of APIs that facilitate using the .NET Framework in a more functional way. These APIs are often directly portable to C#. Let's look at a simple example.

The following C# code is typical of how we might create an array containing the natural numbers from 1 to 20:

int[] a = new int[20];
for (int x = 0; x < a.Length; x++)
  a[x] = x + 1;

There's nothing special about that code. It's representative of the sort of thing that we write all the time. However, it won't fly in the functional world because it's written in an imperative style. That is, the code specifies the exact steps that should be taken to create and initialize the array:

  1. Create a new int array of 20 elements.
  2. Initialize a new indexer variable, x, to 0.
  3. Check to see that x is less than the length of the array. If it isn't, STOP.
  4. Assign the value of the array element at index x to the result of x + 1.
  5. Increment x.
  6. GO BACK to step 3. Repeat as necessary.

In contrast, the F# libraries provide a special module, Array, for manipulating single-dimensional .NET arrays in a more functional style. (Array2 and Array3 are also available for manipulating two- and three-dimensional arrays respectively.) Using the Array module, the C# code above could be translated to F# like so:

let a = Array.init 20 (fun x -> x + 1)

Instead of a specific code recipe, this F# code says (in a more declarative fashion), "create an array of 20 elements, and use this function to initialize each element." An interesting feature of the F# version is that the type of the array is never declared. Because the compiler can infer that the result of the passed function (fun x -> x + 1) will be an int, "a" must be an int array.

To me, this code is beautiful. In addition, it is declarative instead of imperative; it describes what should be done but doesn't dictate exactly how it should be done. When I see such elegant code, I immediately start trying to figure out which of its aspects could be used to improve the code in my daily C# work. Here's how we might "borrow" the F# "Array.init" function in C#:

public static class ArrayEx
{
  public delegate T CreateItem<T>(int index);
 
  public static T[] Create<T>(int length, CreateItem<T> createItem)
  {
    if (length < 0)
      throw new ArgumentOutOfRangeException("length");
 
    if (length == 0)
      return new T[0];
 
    T[] result = new T[length];
    if (createItem != null)
    {
      for (int i = 0; i < length; i++)
        result[i] = createItem(i);
    }
    return result;
  }
}

With this function defined, we can rewrite our array creation sample declaratively using C# 3.0 syntax.

var a = ArrayEx.Create(20, x => x + 1);

Notice that this code takes advantage of the C# compiler's type inference in the same way that the F# sample does. Sweet!

Let's take a look at another example. Suppose we want to iterate through all of the elements in our int array and output each element's value to the console. We have a few of options available to us. First, there's the familiar for-loop approach:

for (int x = 0; x < a.Length; x++)
  Console.WriteLine(a[x]);

Second, there's the more declarative foreach-loop:

foreach (int val in a)
  Console.WriteLine(val);

Finally, the underused "Array.ForEach" BCL method is also a possibility:

Array.ForEach(a, val => Console.WriteLine(val));

In addition, because "Console.WriteLine" has an overload which accepts a single int parameter, we can rewrite the previous code without a lambda expression:

Array.ForEach(a, Console.WriteLine);

Now, for the monkey wrench. Suppose we want to print the index of each element in the array along with the value. With this added requirement, the for-loop is our most attractive choice because the indexer variable is already built in. The other two options would require awkwardly creating an indexer variable and explicitly incrementing it. This additional code looks especially ugly with the "Array.ForEach" option.

int x = 0;
Array.ForEach(a, val => Console.WriteLine("{0}: {1}", x++, val));

Nasty.

How might we handle this in F#? Simple. F# provides an API designed to iterate an array with an index.

Array.iteri (fun x value -> printfn "%i: %i" x value) a

Like the BCL's "Array.ForEach" method, F#'s "Array.iteri" iterates through an array and applies the given function to each element. The difference is that the function to be applied includes an additional parameter representing the element's index in the array.

NeRd Note
Curious about why the parameter ordering of the F# "Array.iteri" API places the function to be applied before the array to be iterated? Isn't that backwards? Wouldn't it make more sense to move the array parameter to the first position? Nope. The parameter ordering is intentional.

Unless specified, F# functions are implicitly curried. Hence, parameters are usually ordered to take advantage of partial application. If the parameters of "Array.iteri" were reordered, we could not easily use partial application to build useful functions from it.
let print = Array.iteri (fun x value -> printfn "%i: %i" x value)

print a
Besides, if passing "a" as the last parameter is awkward, we can always pass it with the F# pipeline operator.
a |> Array.iteri (fun x value -> printfn "%i: %i" x value)
Make sense? OK. Take a deep breath...

Using F#'s "Array.iteri" as a model, we can define an equivalent function in C#.

public static class ArrayEx
{
  public delegate void IndexedAction<T>(int index, T item);
 
  public static void Iterate<T>(T[] array, IndexedAction<T> action)
  {
    if (array == null)
      throw new ArgumentNullException("array");
    if (action == null)
      throw new ArgumentNullException("action");

    if (array.Length <= 0)
      return;

    int lower = array.GetLowerBound(0);
    int upper = array.GetUpperBound(0);

    for (int i = lower; i <= upper; i++)
      action(i, array[i]);
  }
}

Now we can iterate our array and output the index and value of each element to the console with one line of code!

ArrayEx.Iterate(a, (x, i) => Console.WriteLine("{0}: {1}", x, i));

Since we're using C# 3.0, we can declare "ArrayEx.Iterate" as an extension method to make the client code more readable.

a.Iterate((x, i) => Console.WriteLine("{0}: {1}", x, i));

In conclusion, using F# as a source of inspiration, it's easy to create APIs that enable more declarative C# code to be written. Do you have a cool declarative API that you've written for C# or VB? If so, I'd love to hear about it. Feel free to post your creations in the comments or email me directly.

posted on Tuesday, November 13, 2007 11:17:23 PM (Eastern Standard Time, UTC-05:00)  #    Comments [18]

kick it on DotNetKicks.com
 Thursday, November 08, 2007
Putting the Fun into Functional with F#

Scrambling to understand arcane-sounding functional programming terms like "closure" and "currying?" Intrigued by the recent community coverage of Microsoft's F# language, but don't know where to start? Look no further. This overview of functional programming is a wild ride through the five most important concepts using the elegant syntax of Microsoft F#. Note: no object-oriented programmers will be harmed during the session.

That's the session that I'll be presenting at the upcoming CodeMash conference. I'm really excited about this talk.

If you're planning on coming but haven't registered, the early bird discount will expire on November 15th.

See you there!

posted on Thursday, November 08, 2007 1:46:37 PM (Eastern Standard Time, UTC-05:00)  #    Comments [1]

kick it on DotNetKicks.com