Contents
Introduction
This article is going to be using some of the new features available with the new Visual Studio 2008 Beta 2 Professional edition. Download it now if you haven't already. I have been using it for almost 3 months now, and I have not looked back. I now use it for all my HTML and CSS editing, including writing this very article. Not only does it have a host of new features, but you get performance improvements too, and even though it is still a beta version, I have had absolutely no problems or crashes whilst using it.
Some New VS2008 Pro Features
- Multi-Targeting - targets different .NET Framework versions.
- Split View WYSIWYG - view both design and source at the same time.
- JavaScript intellisense and debugging.
- Improved CSS support.
- Nested master pages.
- Unit Testing.
Some New .NET 3.5 Features
I am not going to explain what some of the new features are, but rather leave it to Scott Guthrie and let his blog posts do the talking.
Extension Methods
One of the features that caught my eye straight away was Extension Methods. Extension methods "allow developers to add new methods to the public contract of an existing CLR type, without having to sub-class it or recompile the original type." They also make other powerful features, like LINQ, possible. I also then realized that it is now possible to "add" functionality to the existing framework classes, for example, the System.String
class. I have always had a class of static string utility methods that I use in all my projects and applications. It is a part of a utils class library that I have built and grown over the years while using .NET. So this was the perfect opportunity to rewrite my utilities class library using version 3.5 and take advantage of (and learn) the new features. I have already started doing this, and I am blogging about it as I go.
First Example
An extremely simple (and useless!) example of an Extension Method can be seen in the following code:
namespace Utils.MyExtensions
{
public static class JunkExtensions
{
public static string ToSomethingElse(this string input)
{
return input.PadLeft(10);
}
}
}
Please note that your Extension Methods must be defined inside a non-generic static class. Now, to use the Extension Method, include the namespace in your code:
using Utils.MyExtensions;
...and your new Extension Method is now available to you, as you can see in the intellisense:
When NOT To Use Them
I will be the first to admit that Extension Methods can be both useful and powerful, but when is enough enough? Scott Guthrie says in his post: "As with any extensibility mechanism, I'd really caution about not going overboard creating new extension methods to begin with. Just because you have a shiny new hammer doesn't mean that everything in the world has suddenly become a nail!" You couldn't say it any better than that. Listen to Scott - he knows best. You must not convert all your static utility methods to Extension Methods. What is the point? Do you really want to see a string class that has hundreds of methods available, but you only use 10% of them most of the time? Obviously not.
When To Use Them
You should only convert your most reusable, everyday static methods. Don't just create an Extension Method because you can; create one because you know it will help you code smarter. I create Extension Methods that, I think, improve and extend the framework, and that I feel should also be part of the framework. When I find myself asking the question: "But why didn't they include this method in the framework?", a new Extension Method usually follows shortly after.
Also, make Extension Methods that are just wrappers around your utility methods. This way, the utility code and the Extension Method code can be kept separate, so the developer has the choice to use the Extension Methods or not. This can easily be explained with an example utility method:
public static string CutEnd(string input, int length)
{
if (IsEmpty(input)) return input;
if (input.Length <= length) return string.Empty;
return input.Substring(0, input.Length - length);
}
and here is my Extension Method:
public static string CutEnd(this string input, int length)
{
return Utils.Strings.CutEnd(input, length);
}
This gives the developer the freedom he/she wants, whereby the Extension Method or the static method can be used. Also, only one set of tests needs to be done for both methods.
Strange Behavior
Now, I would have thought that creating an Extension Method that checks for nulls is pretty pointless. My thinking was: "how could I check for null if the object is null - won't I get a NullReferenceException
?" Well, I tested it, and apparently no - you won't get the exception. Here's the Extension Method:
public static bool IsNullOrEmpty(this string input)
{
if (input == null) return true;
return input.Length == 0;
}
Here's some code to test it:
string str = null;
if (!str.IsNullOrEmpty())
{
Console.Write(str);
}
This code runs fine - no problems! Very strange indeed, but at the same time, useful. More can be read about this at http://diditwith.net.
Testing Extension Methods
When developing any code that will be reused again and again (including Extension Methods), writing tests for that code becomes a necessity. This is to ensure the code is both reliable and bug free. When creating a reusable framework that is reused on every project and also likely to change a number of times in its lifetime, testing becomes an absolute requirement! The only smart way to utilize these types of tests is by writing Unit Tests. Unit tests allows you to keep a set of tests that you can run at any time, over and over again, to check for all use-case scenarios. So, when you make a change to a utility method, run the unit tests for that method to make sure it still does what you expect. There are many unit testing frameworks out there, including NUnit which is an Open Source framework written in C#. You can also purchase and/or download add-ins for Visual Studio to allow for unit testing within the IDE, but these are no longer required. There is now built-in Unit Testing functionality in VS2008 Pro. Woohoo!
Unit Testing in VS2008 Professional
With a few simple clicks of the mouse, you can create unit tests for code that you have written. Let's do that for our Extension Method:
- Click the Test menu, then 'New Test'.
- Select the 'Unit Test Wizard' option and click OK.
- Enter the name of your new test project.
- Select the methods you wish to test and click OK.
It's that simple! We have now created a new project called UtilsTests that contains all our tests for the Extension Methods we just created:
Now all you need to do is customize the tests to suite your needs. Here is the generated test code:
[TestMethod()]
public void ToSomethingElseTest()
{
string input = string.Empty;
string expected = string.Empty;
string actual;
actual = JunkExtensions.ToSomethingElse(input);
Assert.AreEqual(expected, actual);
Assert.Inconclusive("Verify the correctness of this test method.");
}
As you can see, it intelligently looks at the input parameters of the method and generates the test for you. All you need to do now is change the input and the expected output, then remove the Assert.Inconclusive
line, add a few tweaks, and you have a working unit test. This is what the test should look like now:
[TestMethod()]
public void ToSomethingElseTest()
{
string input = "abc123";
string expected = " abc123";
string actual = input.ToSomethingElse();
Assert.AreEqual(expected, actual);
}
Obviously, a unit test is only as good as the coder who wrote it, so make sure your unit tests are extensive. Actually, be more extensive than you usually would, and take into account even the simplest cases. In fact, be paranoid when you write your unit test. This way, you will be sure your tests cover every angle.
Now run your tests by clicking Test > Run > All Tests in Solution:
..and see the result in VS2008:
As you can see from the screenshot, not all our tests passed. We now need to delve into the code and see why. So, like you would normally do as a VS developer, place a break point into your failed test code. But this time, instead of just running your tests, choose to run them in Debug mode by clicking Test > Debug > All Tests in Solution:
Now you can step through your code and see why the test is failing:
Conclusion
So we have run through a very simple example of what Extension Methods are and how to write unit tests to test them. I hope this article has created some interest in the new features available in VS2008, as they have dramatically helped me code smarter. I use the unit test features daily with my new utilities project written for the .NET Framework 3.5. For example, every day I seem to change or add functionality to my string utils class, and what better way to know and trust that my changes work than by having a set of unit tests that I can run at a click of a button.
Go check out my String Utils class written in .NET 3.5 with a few handy Extension Methods. There you can download the source which includes the full unit tests for the methods.
History
- 4 Nov. 07: Version 1 submitted.