gpt4 book ai didi

c# - 如何为lambda表达式中的匿名变量编写IEqualityComparer?

转载 作者:太空狗 更新时间:2023-10-30 00:30:03 24 4
gpt4 key购买 nike

我想知道有一种方法可以在 lambda 表达式中为匿名变量实现 IEqualityComparer,或者在任何情况下,我都需要编写类来将匿名变量转换为特定类,并创建一个我需要实现 IEqualtyComparer 的类?

我编写了创建笛卡尔(Decart 的)产生式的代码:我定义了 Decart 类。

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

我为 Decart 类定义了 IEqualtityComparer

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;
}
}

我运行这段代码:

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
}

我想在不为匿名变量定义一个类的情况下运行下一个代码,一个用于实现 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

怎么做?

最佳答案

可以声明IEqualityComparer<T>将委托(delegate)作为 GetHashCode 的实现的实现和 Equals接口(interface)的方法。然后你可以传入匿名方法作为实现。

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 Anonymous object creation expressions
Within the same program, two anonymous object initializers that specify a sequence of properties of the same names and compile-time types in the same order will produce instances of the same anonymous type.

关于c# - 如何为lambda表达式中的匿名变量编写IEqualityComparer?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42455687/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com