Anonymous IComparer implementation

C#

C# Problem Overview


Is it possible to define an anonymous implementation of IComparer?

I believe Java allows anonymous classes to be defined inline - does C#?

Looking at this code I want to define a custom IComparer inline

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
	this IEnumerable<TSource> source,
	Func<TSource, TKey> keySelector,
	IComparer<TKey> comparer
)

C# Solutions


Solution 1 - C#

As indicated in one of the comments below, .Net 4.5 allows this via a static method on the Comparer<> class, e.g. comparing two objects based on the value of a property in the class:

var comparer = Comparer<KilowattSnapshot>.Create( 
        (k1, k2) => k1.Kilowatt.CompareTo(k2.Kilowatt) );

Obviously this can be used inline rather than assigned to a variable.

Solution 2 - C#

Even though you can't create anonymous classes that implement interfaces, you can usually use the Comparison Delegate instead of the IComparer Interface in most cases (like sorting, etc.):

Array.Sort(arr, (x, y) => 1);

Also there are some built-in implementations of IComparer like the Comparer Class or the StringComparer Class...

Solution 3 - C#

The .NET framework version 4.5 provides the method Comparer.Create(Comparison) to create comparers based on a specified comparison delegate (which can be a lambda function). However people who are working with earlier versions of .NET will probably need to implement something similar themselves.

Solution 4 - C#

No, C# does not currently allow inline interface implementations; although it does allow you to create delegates inline through lambda expressions and anonymous methods.

In your case, I would suggest using a ProjectionComparer that makes it easy to use this feature, such as the one listed here.

Solution 5 - C#

No, this is not possible. However, you can get the default implementation of IComparer<TKey> by Comparer<TKey>.Default. Otherwise you'll need to create a parameterized implementation and use an instance of that.

Solution 6 - C#

C# does not allow implementing interfaces using anonymous inner classes inline, unlike Java. For simple comparisons (i.e. comparing on a single key), there is a better way to do this in C#. You can simply use the .OrderBy() method and pass in a lambda expression specifying the key.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
 
 
namespace Test{
    public class Test{
        public static void Main(){
            IList<int> mylist = new List<int>();
            for(int i=0; i<10; i++) mylist.Add(i);
            var sorted = mylist.OrderBy( x => -x );
            foreach(int x in sorted)
                Console.WriteLine(x);
        }
    }
}

Solution 7 - C#

Take a look at these 2 SO questions, they tackle essentially the same problem

Use of Distinct with list of Custom Object

Wrap a delegate in an IEqualityComparer

If you go this way, you should pay special attention to Slaks' comments and Dan Tao's answer about the hashcode implementation

Solution 8 - C#

Array.Sort(arrayName, (x,y) => string.Compare(x.Name,y.Name,StringComparison.CurrentCulture));

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJack KadaView Question on Stackoverflow
Solution 1 - C#David ClarkeView Answer on Stackoverflow
Solution 2 - C#Jaroslav JandekView Answer on Stackoverflow
Solution 3 - C#apokryfosView Answer on Stackoverflow
Solution 4 - C#AniView Answer on Stackoverflow
Solution 5 - C#FemarefView Answer on Stackoverflow
Solution 6 - C#MAKView Answer on Stackoverflow
Solution 7 - C#bottleneckedView Answer on Stackoverflow
Solution 8 - C#user3452906View Answer on Stackoverflow