在LINQ中自定义扩展方法来返回带有比较器的匿名对象

本文关键字:比较器 对象 返回 LINQ 自定义 扩展 方法 | 更新日期: 2023-09-27 18:18:24

我读到当从LINQ到Objects查询中投影一个新的匿名对象时,投影对象将覆盖其EqualsGetHashCode方法,以便执行任何进一步检查相等性的方法将正常工作。

这使我认为实现一个自定义操作符,将投影一个匿名版本的传递在T可能是有用的,以避免覆盖这些方法在我的一些类或创建自定义IComparers。

我想这样使用它:

var newList = list.SelectWithComparer(s => new { s }).Union(List2);

首先,这是个好主意吗?

第二,这可能吗?

我尝试了以下方法,但无法编译代码:

public static class LINQExtensions
{
    public static IEnumerable<T> SelectWithComparer<T>(this IEnumerable<T> source)
    {
        return source.Select(s => new { s });          
    }
} 

编译错误是由于匿名类型不再是原始的T:

Error   5   Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<AnonymousType#1>' to 'System.Collections.Generic.IEnumerable<T>'. An explicit conversion exists (are you missing a cast?)    

有人能帮忙吗?

谢谢

在LINQ中自定义扩展方法来返回带有比较器的匿名对象

匿名类型正确地覆盖EqualsGetHashCode方法,但是这些方法的实现反过来依赖于为该对象定义的属性类型实现的EqualsGetHashCode方法。

例如,如果你这样定义一个对象:

var anonym = new {A = 42, B = "XYZ"};

这个匿名对象的EqualsGetHashCode的实现将调用EqualsGetHashCode的类型为int(因为属性Aint类型)和string(因为属性Bstring类型)。

也就是说,你想要实现的基本上是无用的。事实上,如果你定义了一个匿名类型,它的属性设置为对象s,例如:

var myAnonym = new { s };

必须正确定义对象sGetHashCodeEquals方法,才能在字典/哈希表中正确地作为键。
但如果它们是,那么将对象包装在匿名类中又有什么意义呢?您已经可以在字典中使用它:-)