How to write IEqualityComparer for anonymous variables in lambda expression?

I want to know that there is a way to implement IEqualityComparer for anonymous variables in a lambda expression or, in any case, I need to write a class to convert anonymous variables to a class and create a class where I need to implement IEqualtyComparer

I am writing code that creates a Decart production: I have defined the Decart class.

public class Decart
{
    public int X;
    public int Y;
}

I defined IEqualtityComparer for the Decart class

public class Ext : IEqualityComparer<Decart>
{

    public bool Equals(Decart x, Decart y)
    {
        if ((x.X == y.X && x.Y == y.Y) ||
            x.X == y.Y && x.Y == y.X)
            return true;

        return false;
    }

    public int GetHashCode(Decart obj)
    {
        return obj.X + obj.Y;
    }
}

I run this code:

static void Main(string[] args)
{
    Ext ext = new Ext();
    IEnumerable<int> input = Enumerable.Range(1, 3);
        var secondResult = input
        .SelectMany(x => input.Select(y => new Decart{ X = x, Y = y }))
        .Distinct(new Ext());
    Console.WriteLine(new string('-', 50));

    foreach (var x in secondResult)
    {
        Console.WriteLine(string.Format("{0} {1}", x.X, x.Y));
    }
    //output:
    //1 1
    //1 2
    //1 3
    //2 2
    //2 3
    //3 3
}

I want to run the following code without defining a class for anonymous variables, a class for implementing IEqualityComparer.

    var thirdResult = input
        .SelectMany(x => input
            .SelectMany(y => input
                .Select(z => new { x, y, z })))
                    .Distinct( ???? );

//in this case output need to be like this:
//1 1 1
//1 2 1
//1 3 1
//2 1 2
//2 2 2
//2 3 2
//3 1 3
//3 2 3
//3 3 3

How to do it?

+4
source share
2 answers

IEqualityComparer<T>, GetHashCode Equals . .

public static IEqualityComparer<T> CreateEqualityComparer<T>(T ignore, Func<T, int> getHashCode, Func<T, T, bool> equals) => new DelegatedEqualityComparer<T>(getHashCode, equals);

public class DelegatedEqualityComparer<T> : EqualityComparer<T> {
    private Func<T, int> getHashCode;
    private Func<T, T, bool> equals;
    public DelegatedEqualityComparer(Func<T, int> getHashCode, Func<T, T, bool> equals) {
        if(getHashCode==null) throw new ArgumentNullException(nameof(getHashCode));
        if(equals==null) throw new ArgumentNullException(nameof(equals));
        this.getHashCode=getHashCode;
        this.equals=equals;
    }
    public override int GetHashCode(T x) => getHashCode(x);
    public override bool Equals(T x, T y) => equals(x, y);
}

:

var equalityComparer = CreateEqualityComparer(true ? null : new { x = 0, y = 0 }, a => a.x+a.y, (a, b) => (a.x==b.x&&a.y==b.y)||(a.x==b.y&&a.y==b.x));
var result = input
    .SelectMany(x => input
        .Select(y => new { x, y }))
    .Distinct(equalityComparer);

true ? null : new { x = 0, y = 0 }:

CreateEqualityComparer (T ignore) , T, . true null, , new { x = 0, y = 0 } null .

, :

7.6.10.6
, , .

+5

, .

, ,

public class Decart
{
    public int[] dim;
}

public class Ext : IEqualityComparer<Decart>
{

    public bool Equals(Decart x, Decart y)
    {
        for(int i=0; i< x.dim.Length;i++) 
        if (x.dim[i] != y.dim[i] ) 
            return false; 
        return true;
    }

    public int GetHashCode(Decart obj)
    {
        return obj.dim.Sum();
    }
}
+2

Source: https://habr.com/ru/post/1670821/


All Articles