
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:
- Specifying the type name sometimes makes code easier to read.
- It simplifies porting code backwards (e.g. to compile in an
earlier version of Visual Studio).
- 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.