Nice trick for sorting collection of anonymous objects in one line of code

INTRODUCTION

C# 3.0 introduced several interesting features. They can be really handy during everyday development, although mixing them together might be a bit tricky sometimes. This article demonstrates a very nice trick that can save your butt when you are operating on collections of anonymous type`s objects. 

PROBLEM

Lately I was involved in a project, where I had to bind a custom, hardcoded collection of objects to a ComboBox. It looked like this:

List<object> causes = new List<object>();

causes.Add(new { Value = CertificationCause.Item1, Display = Core.Resources.EnumValues.ResourceManager.GetString(CertificationCause. Item1.ToString()) });

causes.Add(new { Value = CertificationCause.Item2, Display = Core.Resources.EnumValues.ResourceManager.GetString(CertificationCause. Item2.ToString()) });

causes.Add(new { Value = CertificationCause.Item3, Display = Core.Resources.EnumValues.ResourceManager.GetString(CertificationCause. Item3.ToString()) });

After this collection has been constructed, it was databinded to ComboBox:

comboCertificationCause.ItemsSource = sorted;
comboCertificationCause.DisplayMemberPath = "Display";
comboCertificationCause.SelectedValuePath = "Value";

This looked great. Anonymous types provided great service for this problem. Task has been completed and it didn`t took many lines of code to be written, nor it was necessary to create a silly and ugly class like CertificationCauseAndStringClass exposing 2 properties.

The problem occurred however when I have been asked to sort this collection. Simple code snippet like this:

causes.Sort()

wouldn`t work, since this is collection of custom objects and as such require special instructions from the developer. You simply need to pointed out to the compiler how these objects should be sorted. Compiler knows how to sort collections of only simple types - doubles, strings, etc. But it has no idea how to sort collections of objects of custom classes. You can give compiler appriopriate instructions in a couple of ways. In the past the best way to accomplish this task was to define and pass a custom comparer (class that implements IComparer interface). Such comparer was simply telling the compilter when one object is “greater” than the other. Alternative solution would be to make the given class to implement IComparable interface, forcing you to create public int CompareTo(object obj) method (for the same purpose).

But C# 3.0 of course offers much better mechanisms to solve this problem. With a bit help of LINQ, we could sort the given collection by using OrderBy method:

 

Normally you would pass the following argument into this method:

cause=>cause.Display

But in this case causes is collection of objects. And object of type object doesn`t expose property Display. Of course we could cast it to the desired data type, but how to pass this type? Anonymous types don`t have names! So it`s impossible to use as operator, nor it is possible to use Cast<…>(…) method coming from LINQ to cast the whole collection at once. So how to get that anonymous type?

SOLUTION

This is where another C#`s feature comes with rescue – generics. I have constructed a simple method for this purpose:

IEnumerable
<T> Cast<T>(IEnumerable<object> collection, T type)

    return collection.Cast<T>();
}

How to use it? All the magic is hidden in using a simple object of our anonymous type to get this  type, as the following statement demonstrates:

sorted = Cast(causes, new { Value = CertificationCause.Add, Display = "" })

This results in our collection being casted. Now all we have to do in order to sort this collection is to use standard OrderBy method:

sorted = Cast(causes, new { Value = CertificationCause.Add, Display = "" }).OrderBy(ob => ob.Display);

Now it is possible to use that method, since we are not operating on collection of objects any more. Each object in this collection has been casted to its real type, so they all expose Value and Display properties. That`s it. Simple yet useful.

CONCLUSION

All new features of C# 3.0 are very noteworthy and helpful. Most of the times they will let you develop quite complex functionalities in a very limited number of lines of code and in a very fast manner. In rare cases though things may get pretty complicated, forcing you to use different tricks like this one .

 

 

posted @ Wednesday, February 25, 2009 10:04 PM
Print

Comments on this entry:

# re: Nice trick for sorting collection of anonymous objects in one line of code

Left by Poonam at 7/30/2009 6:47 AM
Gravatar
Hi

Is it possible to use this approach for sorting collection of custom types?

For e.g. I have an Employee class and have created an EmployeeCollection class as follows:

EmployeeCollection : Collection<Employee>

Pls help me on how to sort this collection using C# 3.0 features.

Thanks!!

#  re: Nice trick for sorting collection of anonymous objects in one line of code

Left by Martinez at 10/29/2009 3:05 PM
Gravatar
Hi,

yes, it is definitely possible and you can sort them by using simple lambda expression.

Your comment:



(not displayed)

 
 
 
 

Live Comment Preview:

 
«November»
SunMonTueWedThuFriSat
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456