25 February 2008

.NET Collection Management with C# 3.0

Generics in C#, enable you to define classes, interfaces, delegates or methods with placeholders for parameterized types used within. This allows you to define classes that use a generic type, and define the type at the time of instantiation or method calls. This makes your code strongly typed, but makes maintenance easier.
Prasanna describes the improvements in .NET v3.5

Using C# 3.0 to manage a collection of objects

This article looks into some of the new features in C# 3.0 and introduces Linq in managing a collection of objects within a generic List

Introduction

A couple of years ago, I wrote an article entitled “.NET Collection Management” for Simple-Talk. The purpose of that article was to introduce generics and to show how generics can be used to manage a collection of strongly typed objects within a generic List using C# 2.0. Generics allow us to write code without binding the code to a particular type, and at the same time ensures we can use strongly typed objects. I thought I’d revisit the article to see how much my code would be simplified and improved in C# 3.0, and introduce some of the new features in C# 3.0.

Let us define an Employee class that we will be using throughout the examples in this article. The Employee class has the properties Name and Salary.

We have omitted the implementation of the properties because their implementation is very simple.  You set a value to a private field and get the value from a private field. So we are going to let the compiler implement the properties for us. This is a feature called “Automatic Properties” that saves a few lines of code and improves the readability of the code when the property implementation is very simple.

Next we will define and use a collection of Employee objects using a List<T>.

In this code, we have used a special syntax in initializing the property values at the time of creating Employee objects. This is a feature called “Property Initialization” that provides a very easy way of initializing one or more properties when creating an object.

Sorting a List

We can use the Comparison delegate and pass it into the Sort method of List<Employee>. In the following code we will use an anonymous method to pass the instance of a Comparison delegate to do the sorting operation. The anonymous method simplifies the call to the Sort method since we do not need to define a separate method.

We could have written this code in C# 2.0. But in C# 3.0 we can further simplify the implementation by using Lambda expressions for method implementations. Lambda expression is an inline method implementation that is translated to an instance of a delegate by the compiler. These expressions use the syntax “(parameter 1, parameter 2 …) => method implementation”. Lambda expressions allow us to define methods on the fly with a simpler syntax compared to anonymous methods. So the above code can be simplified by using the Lambda expression syntax as follows:

By using the Lambda expression, I have omitted defining the type for emp1 and emp2. Since the Sort method accepts an instance of a Comparison delegate for Employee objects, the compiler is intelligent enough to understand that emp1 and emp2 has to refer to Employee objects. The expression “(emp1, emp2) => emp1.Salary.CompareTo(emp2.Salary)” will be translated to an instance of the Comparison delegate.

Another way of sorting the generic List is by using the static method Enumerable.OrderBy. This method will return an ordered collection of Employee objects

The OrderBy method is an extension method. An “Extension method” is a new feature in C# 3.0 that allows you to call a static method belonging to a class as if it is an instance method  belonging to an object. This also allows us to extend types which normally we might not be able to extend. So the OrderBy method can be called as if it is an instance method because it is an extension method. The compiler would replace it as a call to the static Enumerable.OrderBy extension method:

Searching a List

The generic List has the methods Find or FindAll to search for one or more objects within the List. Both these methods accept an instance of the Predicate delegate as a parameter. The Predicate delegate instance can be defined by creating a method or an anonymous method or a lambda expression.

We can also use the Enumerable.Where extension method to search within the generic List. The following code segment returns a collection of Employee objects where the Salary property value is greater than 1000.

There are many operations that are available through extension methods that can be performed on objects within a List. Most of these operations require looping through the objects within the collection. But with the use of extension methods, we can perform these operations without the need to loop through the collection.

For example let us assume we want to retrieve the maximum Salary amount within the collection of Employee objects within List<Employee>. We can use the Max extension method as show in the below code:

Similarly we can use many other operations such as Min, Sum, and Count that are available.

List Conversion

Converting a List of one type to a List of another type is very simple. We can still use the Converter delegate that was available in C# 2.0. Another way of converting the type of a List is to use the Enumerable.Select extension method.

This method call would return a collection of employee names. However, let’s assume that we want to convert the collection of Employee objects into a collection of objects that has the name of the employee and a boolean value indicating whether the employee has a salary over 1000. We would need to create a new type as a class or a structure that has a string property and a boolean property. C# 3.0 supports a new feature called “Anonymous Types” that allows us to define types on the fly.

We’ve defined a new type that has the properties Name and BigSalary. Another thing that you might have noticed here is the use of the new keyword “var”. This is a new feature called “Type Inference”.  Type inference is used when we do not know the name of the type of the variable and we require the compiler to help us out in inserting the name of the type. This is used with anonymous types, since the compiler defines the type anonymously.

Linq

We went through sorting, searching, performing operations and converting a collection of Employee objects in a generic List. The extension methods OrderBy and Where returns an IEnumerable of the type that we use within the generic List – in this instance the Employee type. The extension method Select return an IEnumerable of the type we want to convert the employee objects to. We can combine these extension methods to search, sort and convert the objects within the generic List

This is where Linq comes in. Linq stands for Language INtegrated Query and provides a SQL like syntax for accomplishing what we did in the above code.

This code uses Linq to query the collection of Employee objects. The syntax is very similar to SQL except that  the select clause is at the end of the query expression. It makes sense because the process of converting the objects within the generic List would be the last step. Each expression in the Linq statement followed by the where, orderby and select keywords are lambda expressions. These lambda expressions are used to make method calls to the extension methods as shown in the above examples.

Conclusion

This article looks at the capabilities of the new features in C# 3.0 that helps to better handle collection of objects. It also introduces language integrated query and how it helps in managing collections.

Keep up to date with Simple-Talk

For more articles like this delivered fortnightly, sign up to the Simple-Talk newsletter

This post has been viewed 46878 times – thanks for reading.

Tags: , , ,

  • Rate
    [Total: 108    Average: 3.8/5]
  • Share

Amirthalingam Prasanna

View all articles by Amirthalingam Prasanna

  • Merill Fernando

    Quick Tip
    Good article.

    You can event omit the () when using object initializers.

    new Employee() { Name = “John”, Salary = 25500 }

    can be written as

    new Employee { Name = “John”, Salary = 25500 }

    Cheers!

  • Srikanth

    Well Done
    I knew that you are a big fan of Collections framework. Great work indeed.

  • Amber

    Simply Elegant
    I had learned C and C++ four years ago for my exams and promptly forgotten both the languages after the exams. This article has helped me recall a few of the forgotten coding principles of C and C++. It has also helped me gain insight into the world of C#. What more can i say! A few more such articles and some practice exercises and I’ll be able to tell C# like the back of my hand.

  • Sathiyaseelan Arulanandam

    It must reach
    Mr. Amirthalingam Prasanna has given strong and versatile introductions with a very…very… simple understandable smooth flow example

    Actually one developer can change the style by your great article in 30 minutes….
    Guru knows how to feed shiya :)..yes that is true.

  • alasdair cs

    Nice work
    Good article – particularly the smooth explanation of linq as successive application of lambda expressions to extension methods.

  • Tim

    Nice acticle
    I initially scrolled through it trying to find the C# 3.0 stuff but, not finding it, read the entire article. Nice way of incorporating the new features in your article! I never knew you could use anonymous methods in C# 2.0. I’m definitely loving lambda expressions now though.

  • Anonymous

    article. Nice way of incorporating the
    article. Nice way of incorporating the new features in your article! I never knew you

  • Ben

    Thanks
    Thanks – this makes me want to get myself a copy of Visual Studio 2008 and have a play! I hope the 90 days you get with the evaluation will be sufficient!

  • Anonymous

    hi
    that it

  • Anonymous

    asp.net + C#
    how i can make the commints as this in asp.net

    my email : abctawil@yahoo.com

    pleas send to me.

  • Anonymous

    .NET 3.5
    I’m sorry to correct you, but all the stuff you are talking about was introduced in .NET 3.5.
    .NET 2.0 is merely a collection of new APIs like Workflow Foundation, Presentation Foundation and doesn’t change anything at the .NET 2.0 base language.
    Regards
    René

  • Anonymous

    .NET 3.5
    I’m sorry to correct you, but all the stuff you are talking about was introduced in .NET 3.5.
    .NET 3.0 is merely a collection of new APIs like Workflow Foundation, Presentation Foundation and doesn’t change anything at the .NET 2.0 base language.
    Regards
    René

  • Prasanna

    Re: .NET 3.5
    Yes , All the features I hv mentioned here are of .NET 3.5 as specified in the article. C# 3.0 is part of .NET 3.5. In .NET 3.0 we used the same C# 2.0 version with no changes from .NET 2.0.

  • Nagaraj L Gowda

    hi
    Good article

  • javad

    ebook about c#
    please send a good ebook about c#
    my Gmail: mjsh86mech@Gmail.com

  • DrFooMod2

    Version Numbers
    The versioning of .NET lately is idiotic. 3.0 should have been 2.1 (or 2.5 at best), and the latest should be 3.0. That way C# 3.0 matches the Fx version. Duh.

  • Willy Wang

    Thanks
    Good article. Thank you.

  • sandy060583

    great article
    hi Prasanna,

    Really a Great Article,

    You have Explained C# 3.0 features with Collections very smoothly & Effectively.

    Your way of writing explanation is excellent.

  • kuldeep rana

    To the Point.. Good Article
    To the Point.. Good Article

  • Dhanesh

    Thank
    Nice Article Sir!