Sorting c#1 to c#4

Consider if we have list of Products and we want them to be ordered by Product Name, Below is how it might be implemented in c#1

In C# 1

class ProductNameComparer : IComparer
 {
   public int Compare(object x, object y)
   {
     ProductsSortingInCSharp1 first = (ProductsSortingInCSharp1)x;
     ProductsSortingInCSharp1 second = (ProductsSortingInCSharp1)y;

     return first.Name.CompareTo(second.Name);
   }
 }

     ArrayList products = ProductsSortingInCSharp1.GetSampleProducts();
     products.Sort(new ProductNameComparer());
     foreach(ProductsSortingInCSharp1 product in products)
     {
       Console.WriteLine(product.name);
     }

So as you can see to just sort the products we had to create a whole new class altogether, which has to implement IComparer, mention not this is only for one sort order, if we have to sort products both by name and price, then the job become tedious.

Also, we can see following issues with ProductNameComparer Class,

  • There are explicit casts in the code, casts are a way to tell the compiler that you know more information than it does and that means there is a chance that you might be wrong.ex: if ArrayList returning from GetSampleProducts were to return a string then there is a chance of run time error.

C#2 generics will address this issue,

List products = ProductsSortingInCSharp2.GetSampleProducts();
products.Sort(new ProductNameComparer());

class ProductNameComparer : IComparer<ProductsSortingInCSharp2>
 {
   public int Compare(ProductsSortingInCSharp2 first, ProductsSortingInCSharp2 second)
   {
     return first.Name.CompareTo(second.Name);
   }
 }

Still for comparing we have to create a class implementing an IComparable interface,  in C#2 this can be achieved using the delegate.

products.Sort(delegate (ProductsSortingInCSharp2 first, ProductsSortingInCSharp2 second)
{
  return first.Name.CompareTo(second.Name);
});

As you can see using delegates and anonymous methods in C#2 we had eliminated the creation of explicit class for comparison.

Only Problem I see with the above code is, readability is missing and C#3 lambda expression’s would come to our rescue here,

Sorting using Comparison from a lambda expression (C# 3)

List<ProductsSortingInCSharp2> products = ProductsSortingInCSharp2.GetSampleProducts();
 products.Sort((x, y) => x.Name.CompareTo(y.Name));
 foreach (ProductsSortingInCSharp2 product in products)
 {
   Console.WriteLine(product.Name);
 }

Ordering List using an extension method in C#3

    List<Product> products = Product.GetSamplesProducts();
     foreach (Product product in products.OrderBy(p =>p.Name))
     {
       Console.WriteLine(product);
     }

Please note that here we are NOT actually modifying the list in place, i.e if you print Products again you would see that the list has not been changed.

If we note the changes from C#1 to C#3 here it goes

  • C#1, Weakly typed comparator. No delegate sorting option
  • C#2, Strongly typed comparator. Delegate Comparisons and Anonymous methods
  • C#3, Lambda Expressions, Extension Methods and Option of leaving list Unsorted
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s