Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Icomparer with argument

How would an IComparer that needs an argument be implemented (might not be relevant but I'm using it on Linq query)?

I suppose it should be called like this:

ListOfObjectsToSort.orderBy(x => x, myCustomComparer(argument));

And this is what i found on how to implement the IComparer but i can't figure out how to change it to pass the argument here:

public class MyComparer : IComparer<object>
{
    public int Compare(object x, object y)
    {
       // code will then return 1,-1 or 0
like image 335
Afonso Avatar asked Jan 29 '15 22:01

Afonso


2 Answers

You can't add an argument to the Compare method or you violate the interface contract. Add a property to the class that can be used in the method:

public class MyComparer : IComparer<object>
{
    public int MyArgument {get; set;}
    public int Compare(object x, object y)
    {
       // code will then return 1,-1 or 0
       // use MyArgument within the method       
    }

You can set it in the constructor:

public MyComparer(int argument)
{
    MyArgument = argument;
}

Then your syntax would be:

var myCustomComparer = new MyComparer(argument);
ListOfObjectsToSort.orderBy(x => x, myCustomComparer);

or just

ListOfObjectsToSort.orderBy(x => x, new MyComparer(argument));
like image 170
D Stanley Avatar answered Oct 20 '22 22:10

D Stanley


the problem is that this cannot be done exactly as you're asking.

The reason for this is that you're trying to change the signature of the Compare method, which would result in outside libraries (like Linq!) being unable to call the method, because the arguments they pass are no longer the arguments needed. Thus, the compiler simply does not allow this.

However, there is a way around this, for this particular case, in that since IComparers are used as objects, you could create a class which implements IComparer and takes a custom object in the constructor, saving it to a field and using that for comparison calculations. Thus, you end up with

var comp = new CustomComparer(argument);

ListOfObjectsToSort.OrderBy(x => x, comp);
like image 2
David Avatar answered Oct 20 '22 23:10

David