Wednesday, December 23, 2009

Useful Extension methods

I've posted in the past about the hazards in extension methods and how they can be easily abused. there are plenty of links out there specifying the cons of using this feature.
However, since the title got you in here, I'm assuming you are still interested.
I wanted to share some of the most common extension methods I use when writing code.

IsNullOrEmpty - I think we all know this method from the String class. Why not have the same capability on collections?
I did see plenty of samples on the web showing how to add this method to collections or arrays.
things like:
public static bool IsNullOrEmpty(this ICollection collection)
{
    return collection == null || collection.Count == 0;
}

This is all fine and will return True if the collection/Array are null or empty.
But hey, what about some other, non "ICollection" objects that implements IEnumerable like XmlNodeList?
For that purpose, we can't use the Length or Count properties since we don't have them.
So, let's work with the IEnumerator.
Initially, the enumerator is positioned before the first element in the collection so calling Current will throw an exception. By calling MoveNext we move the enumerator to the first element and the bool value will tell us if it is empty or not. Complicated?
public static bool IsNullOrEmpty(this IEnumerable iEnumerable)
{
    if (iEnumerable != null)
    {
        return !iEnumerable.GetEnumerator().MoveNext();
    }
    return true;
}

Now, since collections and arrays implements IEnumerable we are clear to go.
static void Main(string[] args)
{                        
    List<string> list = new List<string>();
    Console.WriteLine(list.IsNullOrEmpty());//This will print True
    list.Add("Some text");
    Console.WriteLine(list.IsNullOrEmpty());//This will print False
}

But wait, didn't I say "some" extension methods?
Another one I use when I'm writing console applications is:
public static void Print(this Object obj)
{
    Console.WriteLine(obj);
}
I use this trick when I need to change the output target according to configuration or command line input.
The result will look this:
static void Main(string[] args)
{                        
    List<string> list = new List<string>();
    list.IsNullOrEmpty().Print();//This will print True
    list.Add("Some text");
    list.IsNullOrEmpty().Print();//This will print False
}

Monday, December 14, 2009

Bad names

I've recently done code review for someone and stumbled on a GeneralUtils.cs file I didn't see before.
"OMG!!!" I said "it is general for sure, and provides some utils right? what kind of utils?"

Him: Grinning as if his hand was caught in the cookie jar. "A bunch of things related to X,Y and Z objects"
Me: "Well, X Y and Z handles 3 different things right?"
Him: "Yes but I didn't think they deserve an independent class"

The name is bad for sure and I got no objection on that. the thing is, it hides a much bigger problem. The object is doing too many things instead of focusing on just one. This means that the Single responsibility principle was violated.
I usually have a small question that clears the issue in a second. ask yourself what does the class/method is doing. if the answer is "It does x AND y" then a re-factor session should visit your code.

Him: "I see your point. I'll split them to 3. I thought of calling the first one XHelper"
Me: "Sounds good. this means that XHelper will help the X class right?"
Him: "No, I don't have an X class"
Me: "Let's suppose you have an X class, X will call XHelper right?"
Him: "Yes. and?"
Me: "So, if the helper is doing all the work it would make more sense to move it into X. if it doesn't, please give a more descriptive name"
Him: "But I don't have an X class!!!"
Me: "Even better! who are you helping?"

Monday, May 18, 2009

Visual Studio 2010 beta 1 is here!

Well, its about time! the beta version is now available for MSDN subscribers.
They also said that it will be publicly available on Wednesday for all non MSDN users.

Sunday, April 26, 2009

C# 4.0 - Collection of links

I've just came across this great post at Bogdan Brinzarea’s blog.
The post contains plenty of links on each of the new features in the new framework.

Enjoy!

Friday, April 24, 2009

//Magic. do not touch

I've stumbled upon this hilarious post in stackoverflow under the title of "What is the best comment in source code you have ever encountered?".

As the title implies, this was my favorite!
I also like this one as well :)

//
// Dear maintainer:
// Once you are done trying to 'optimize' this routine,
// and have realized what a terrible mistake that was,
// please increment the following counter as a warning\
// to the next guy:
// total_hours_wasted_here = 16
//

Thursday, April 23, 2009

Find a key by its value in a NameValueCollection

While I was working one of my samples, I came across a nice problem: "How do I get a key from a NameValueCollection by its value?"
Assume the following declaration:


NameValueCollection nvc = new NameValueCollection { { "a", "abc" }, { "b", "bcd" }, { "c", "cde" } };

Well, I can try to explain why I needed it but I assure you it wasn’t so important. In fact, the only added value of this sample was me finding a nice solution to this problem :)

Back to the point, there was, of course, the strait forward solution of iterating on the list and checking for a match on each value but that was too ugly even for a sample.
So, why not recruit LINQ to the rescue?
A small attempt made me realize that though the collection implement IEnumerable, the enumeration works only on the keys so still no cookies for me.

Couple of more hits on the head with a club made me remembered that I have Extension methods in my arsenal. I know I had previously warned about in this post.
Well, I guess it can now come in handy.


public static class SampleExtensions
{
public static IEnumerable<KeyValuePair<string, string>> GetPairs(this NameValueCollection coll)
{
if (coll == null)
{
throw new ArgumentNullException("throw something here");
}
return coll.Cast<string>().Select(key => new KeyValuePair<string, string>(key, coll[key]));
}
}

Nothing fancy here. The cast was done so I could use the select method.


var result = (from pair in nvc.GetPairs() where (string.Compare( pair.Value,"abc")==0) select pair.Key);

result.ToList<string>().ForEach(str => Console.WriteLine(str));

Now for the usage. The search is now done on a KeyValuePair and now I have access to the value in each pair.
The last line prints the result to the console and there you have it.

Ugh!
I'm sure there was a good reason why this feature was left on the drawing board.

Thursday, March 19, 2009

ASP.NET MVC release version is now live!

Alas!

MVC 1.0 release version was finally published and can be downloaded here.

This came as a surprise since the RC2 version was only published couple of weeks ago and the release version was quite silent.
The changes included in the RC2 where a bug fix and a JQuery version upgrade so no broken APIs should be expected.

While you are on it, I suggest downloading this free chapter of MVC book.

Friday, March 13, 2009

Visual Studio 2010 CTP expiration problem

Couple of months ago, Microsoft published the Visual Studio 2010 CTP version at this link. The files total size was a whopping 7GB. when extracted it took another ~24GB of space. the reason is that it contains a full Virtual pc environment running Windows server 2008 and VS2010 already installed.

The problem was that on the first of January 2009 the version had expired and couldn't be used any more. Jeff Beehler posted a temporary solution in his blog on how to override this problem in case you need more time to evaluate it. Remember, do the change before you open the VS2010.

BTW, this will also solve the nagging windows activation message.

Thursday, February 26, 2009

Visual Studio 2010 is having a new look

Jason Zander, the General Manager for Visual Studio, presented in his blog some more details and pictures about Visual Studio 2010.

I'm sure that there is more into it then meet the eye but what I really liked in the update was the new Extension manager. The tool will be able to browse for third party templates and tools online and to install them in your environment. Cool!

The Library can be browsed at Visual Studio Gallery.

Monday, February 23, 2009

Integrate ASPX compilation into Visual Studio

One of the principles I insist on is to always try my build on a clean environment and simulate installation as if it was done by QA. Lately I've noticed that I keep falling on errors hidden deep in the aspx files. So, why not using the old and familiar aspnet_compiler.exe tool? It is located at C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 and it is quite easy to use.

As a VS add-ins freak I've started thinking on an amazing add-in that will integrate to the VS and will listen to build events and display the results at the output pane. Heck, why not add some coffee serving capabilities?

It took me about 10 minutes of googling to stumble on this blog. Mike Hadlow had a genius in its simplicity idea. Use the POST BUILD EVENT!
All I need to do is put the following line in the post build event: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_compiler.exe -v / -p "$(ProjectDir)\"

Now, All that is left is to make the process of adding this line to each and every web project in our team to be automatic.

I have just the add-in for that :)

Saturday, February 21, 2009

Respect your extension methods

One of the nice things in C# 3.0 is extension methods. I won't go into details about it but would like to focus on the hazards when actually writing beyond the plain examples.
However, I will use a plain example myself since I don't want you to fall asleep.

Since the method binding is done at compile time, you will get a different behavior depending on the assigned type.

Suppose we have 2 (plain) objects:


public class BaseObject
{ }
public class DerivedObject : BaseObject
{ }

Now for the extension method:


public static class ObjectExtensions
{
public static void ExtensionMethod(this BaseObject obj)
{
Console.WriteLine("In BaseObject extension version");
}
}

The Main method is very simple:


static void Main(string[] args)
{
BaseObject baseObj = new BaseObject();
DerivedObject derObj = new DerivedObject();
baseObj.ExtensionMethod();
derObj.ExtensionMethod();
}

I've declared 2 objects and when I run this sample I get:
In BaseObject extension version
In BaseObject extension version

So far so good; 2 object, 1 extension and 1 expected result for both calls.
Remember the compile time binding thing? Lets add the another version for the extension method. It goes like:


public static void ExtensionMethod(this DerivedObject obj)
{
Console.WriteLine("In DerivedObject extension version");
}

Now, when running this sample again, I get:
In BaseObject extension version
In DerivedObject extension version

"Is he ever going to get to the point?"
Well, the point is this: add these 3 lines to the main method and see what happens.
BaseObject[] arrOfObj = { baseObj, derObj };
arrOfObj[0].ExtensionMethod();
arrOfObj[1].ExtensionMethod();

We are back to BaseExtension for both new calls even though one of them is a derived type.

The danger is obvious. It is very easy to keep your gourds down and write some buggy lines of code that will make you bold trying to figure out what the heck went wrong.
Of course, there are other words of caution in this subject:

When it comes to your extension method versus the original object version, yours will always loose. The extended version will never be called.
"Why the heck would you extend a method that already exists?"
Well, the first option is that it didn't exist at the time and was added to the object at a later point of .net life. You know, great minds think alike.
The second option is that I tried to override the original behavior. No treats for me in both poor scenarios!

"Well, am I at list entitled to access some private fields of the extended object?"
Hmm, no! You see, extension method is just a way to call a static method from the instantiated object.

You will find many great examples on how to do nifty things with extensions.
My advice is to avoid it if you can inherit and add it in the derived object. In case you can't or don't have access to the code then use it with care.