Archive for November, 2007
MSDN Subscription
Just had to share: my “Welcome to MSDN” email just showed up. And hey, it only took 7 days and 12 hours! Three cheers for the largest tech company in the world!!!
No commentsUpgrade your C# Skills part 1 – Extension Methods
DOWNLOAD the Code!
Now that I have VS2008 and .NET 3.5 installed, I am going to begin a series of articles on some of the new features you can use in C#. My hope is to add one new article a day for the rest of this week. Along the way, we’ll explore some of the new language features for C# 3.0. Truthfully, they aren’t all that new since C# 3.0 has been around for about a year, but support for them is now built in to Visual Studio, so using them is now realistic. Also, with the release of VS208, I’m sure this will be the first time most developers will be exposed to them. I’m going to start by introducing one of my favorite enhancements: Extension Methods.
Extension Methods
Extension methods offer us a way to expand class functionality even if we do not have access to the code for those classes (including sealed classes). In other words, we can add our own functionality to any object type. Have you ever looked at the String class and said “why can’t I do {fill in the blank} with a String?” If so, you probably created your own method, passed it the string in question, and consumed the return value:
string z = Reverse(s);
If you’ve ever written code like this, then Extension Methods are for you. In the case above, it should be obvious that Reverse is a static method, since it is not attached to an instance. Wouldn’t it be nice instead to write this?
string z = s.Reverse();
I know it is a subtle difference, and in this case not a terribly functional one, but hopefully you can see the difference. Instead of passing the string variable to a static method, you can treat your methods as though they belong to the string class. And these new methods are available in Intellisense: when I type “s.”, I will see my extension methods right alongside all the native methods, which makes finding and using them much more palatable. And you will find in the new Intellisense that Microsoft itself is making heavy use of Extension Methods. You can tell in two ways: first, the icon for extension methods is the familiar purple box but accented with a blue down arrow. Secondly, when the method description pops up in Intellisense, the description is preceded by “(extension)”.
Let’s look at a more reasonable example. Using the Regex class, you can determine whether or not string matches a Regular Expression pattern by passing a string and a pattern to the Regex.IsMatch() method:
if (Regex.IsMatch(s, "awe"))
{
Console.WriteLine("Yep, this is a match!");
}
else
{
Console.WriteLine("Sorry, no match.");
}
I think it would be handy on occasion to simply “ask” the string itself if it matches a certain pattern:
if (s.IsRegexMatch("awe"))
{
Console.WriteLine("Yep, this is a match!");
}
else
{
Console.WriteLine("Sorry, no match.");
}
Pretty neat, huh? OK, I admit it doesn’t appear to lessen your code, but to me it can make your code make more syntactic sense. And given a more complex example, it could do a lot for you. Richard Hale Shaw showed us an example of a .ForEach extension for IEnumerable<T> collections that would knock your socks off! Imagine being able to loop through an entire Collection and perform some action on each item in a single line of code, without passing the Collection off to a method? It would look something like this:
FileInfo[] files = dir.GetFiles();
files.ForEach<fileinfo>(f => Console.WriteLine("{0} {1}", f.FullName, f.Length));
For now, ignore the code between the () – that’s a Lambda Expression, and we’ll get to those later in the week. Just understand that with this sample above, each FileInfo object in the array will have the passed Action applied to it. How many foreach loops do you think this little nugget could eliminate?
Now, I hope this will get you interested in Extension methods: it didn’t take me too long to think these are very cool! To get you started, I’m adding a new project called DevelopingForDotNet.Extensions to the Free Code page . My take on Richard’s method(s) are included, along with a handful of String and Numeric operations. Nothing too fancy, but hopefully enough to help get you started.
Enough already, how do I do it?
Creating Extension Methods is very simple. First, you must follow these simple rules:
- Extension Methods must be static, defined in a static class
- Extension Methods must be public
- The this keyword precedes the first parameter
We’ll take these one at a time. First, the method must be static because of how the compiler handles extensions. Behind the scenes, whenever an Extension Method is employed, the compiler actually generates code to call the static method. The idea of the Extension Method is just a visual layer for the developer: behind the scenes the actual static method is being called. Also, these methods can be called in a static fashion, rather than as methods attached to an instance. Which brings up another good point: the class name the Extension Methods are in is essentially irrelevant (unless you are going to call them explicitly). I put all my extensions in a single static class (imaginatively called “ExtensionMethods”).
Second, they probably do not absolutely have to be public, but if they aren’t then you are severely limiting the functional scope, so what’s the point?
Finally, preceding the first parameter with “this” is what tells the compiler that this is an Extension Method. It is also probably going to be the main source of initial confusion, because you do not pass this parameter (unless you are calling the method explicitly).
Overall, these are fairly simple rules to follow. Here is a handy method I’ve used for a while:
{
string ch = FillCharacter.ToString();
if (s.Length > Size)
{
throw new ArgumentException("Size of Value larger than Requested Size.");
}
while (s.Length < Size)
{
s = ch + s;
}
return s;
}
This method receives a string and right adjusts it to the given size, filling the leading characters in with the passed char. Calling it looks like this:
s = RightAdjust(s, 7, ’0′);
// Value of s is now "0001234"
Now, let’s convert this to an Extended Method:
{
string ch = FillCharacter.ToString();
if (s.Length > Size)
{
throw new ArgumentException("Size of Value larger than Requested Size.");
}
while (s.Length < Size)
{
s = ch + s;
}
return s;
}
All we did was add “this” before the first parameter. Now we can call it like so:
s = s.RightAdjust(7, ’0′);
// Value of s is now "0001234"
Naturally, you will need to add a reference to the DLL that contains your Extension Methods in order to find and use them.
Overloading Extension Methods:
Just like other methods, Extension Methods can be easily overloaded. My approach for overloading has always been to put all the functionality in the method that requires the most parameters. I then simply have my overloading method signatures call the primary method, sending it the appropriate parameter values. Looking at the RightAdjust method above, I want to establish a method that will use a blank character as the default fill character if one is not supplied. What’s different about overloading extension methods, is that I actually employ the primary extension method in my overloading methods:
{
return s.RightAdjust(Size, ‘ ‘);
}
So now I can call this method passing it just the Size parameter, and that method then calls the primary method using the Extension Method mechanism.
Conclusion:
Extension Methods can be as simple or complex as you like. They are a nice syntactical enhancement to the language that lets you enhance other objects and use them how you would like. But beware: you could easily go overboard. I mean, there is no reason to create a MakeDirectory method for a TimeStamp instance, but you could. Just use common sense and make sure that the extensions you create apply to the object type and way that you would use them.
9 commentsInstalling VS2008
FINALLY! After 5 hours and 45 minutes of downloading, the ISO file is here! I also downloaded Microsoft’s VirtualCD software, mounted the ISO file, and began the Install process at 3:01pm EST.
First, after mindlessly bypassing the EULA, I saved 1.6 GB of install space on my machine by not installing C++ or Crystal Reports. I’ve had C++ since I first installed VS2003 Pro and have never once used it, same for Crystal Reports, so why bother? I could have saved more but not installing SQL Server, but I figured better safe than sorry.
A few things about this machine while the installer runs:
- IBM ThinkPad G41, about two years old, with some kind of Pentium IV Mobile processor.
- Running Windows XP Pro SP2.
- It had a little over 8 GB free when I started.
- 1 GB RAM.
- Already installed are VS2005, Mobile 5.0 SDK, .NET 3.0 (and 2.0 and 1.1)
4:18pm -
The install is finished. I had to reboot, which meant remounting the Virtual CD image. Also, I cannot install the MSDN Documentation: the installer will not recognize the ISO image as the correct disc. Perhaps there is a separate download from MSDN for the docs.
At any rate, it seems I am up and running. I opened the IDE for the first time and selected C# as my primary environment. The software configured and opened a few minutes later.
So all in all, the installation was a breeze (except for the waiting for the download part). Now on to Blend!
No commentsSite Update
Since I am stuck waiting for VS2008 to finish downloading (again – currently at 35%), I thought that I would address something that has bugged me here for a while. I’ve never liked the option employed for showing code on the site. It’s ugly and bulky and does not handle line breaks, indenting, or syntax highlighting. Here is an example of what it used to look like:
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
lblIsFirstTime.Text = “This is the first call.”;
}
else
{
lblIsFirstTime.Text = “This is a PostBack”;
}
}
I hit the Google pavement today and found a WordPress Plugin for Code Highlighting. It installed easily and I went to work right away replacing the old code wrappers with this one. Now the examples should look like this:
{
if (!this.IsPostBack)
{
lblIsFirstTime.Text = "This is the first call.";
}
else
{
lblIsFirstTime.Text = "This is a PostBack";
}
}
I turned off line numbering, which is a plug-in wide setting, but I might fiddle with it to see if I can turn it on and off an runtime with an attribute. It would be handy for some examples to be able to reference line numbers. Also, I’d like to see if I can make it horizontally scrollable since some of the code wraps and isn’t as visually appealing (although it should copy and paste into your IDE just fine.)
I’ve gone back through all the old posts that show code and made this upgrade, so I hope you find them more usable now. Thanks to Dean Lee for a very useful plug-in.
UPDATE (94% downloaded):
I did correct the wrapping/scrollable issue mentioned above. This way, code actually looks as intended and preserves the original line break integrity.
I looked at the line number question also, but I do not see how I can make that change, at least not with some serious investigation, which I am not prepared to do. It functions well enough now as is. I also experimented with the color scheme, trying to make it closer to how Visual Studio highlights, but I actually like this way better. It has a few quirks though: for one, I cannot get “foreach” to color properly (even though it is in the Syntax array right next to “for”. I even tried reordering them in case it was a lookup bug, but no dice). There are a couple of other small items, but none of them detract from the code, so I’m not going to fuss with it anymore for now.
No commentsMSDN Notes from a first time subscriber.
If you’ve been following my journey, you’ll know that Monday morning, after 4 years as a .NET developer, I finally subscribed to MSDN. I did so in anticipation of the release of Visual Studio 2008, which occurred Monday afternoon. Needless to say, I was very excited by all this. My excitement began to dwindle though, the longer I had to wait to get confirmation of my MSDN subscription.
Finally, Tuesday afternoon, I was able to get confirmation over the phone and received my Subscriber Benefits Number (the magic number that lets you in to all of MSDN’s goodies). Oh, and I still haven’t received any kind of email notification that the process has been completed, so if I hadn’t gotten impatient and called I’d still be waiting.
So yesterday afternoon I began the VS2008 RTM download. It is 3.31 GB, so it will naturally take a long time to download. When I left to go home, it was about 30% finished. I figured that it would finish downloading, and that this morning I would be knee-deep into installation. Unfortunately, at 2.01 GB, the Download Manager experienced a fatal error. I could not resume the download and had to restart it again from scratch this morning. I feel like Charlie Brown when Lucy pulls the football up on him at the last second. Good Grief!
OK, so I’m just full of complaints today:
- It seems I have to reenter my Live password every 3-4 pages. I’ve reenterred it at least three times in the last 40 minutes (and that is with the “Remember my userid and password” box checkd on the login page.
- One time when I reentered the login, I was sent to a “Session expired page” and had to log in AGAIN.
- I like the MSDN interface better than the MSDN Subscriber interface, it would be nice if they standardized the two.
OK, so I’m just nitpicking this morning because I’m frustrated. I really hope I can finish this download today so I can play over the holiday! (Sheesh, now I’m rhyming. Time to quit for now…)
No comments
