我读到当从LINQ to Objects查询中投射新的匿名对象时,投影对象将覆盖其Equals
和GetHashCode
方法,以便执行检查相等性的任何其他方法将正常工作
这让我觉得实现一个自定义运算符会生成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?)
有人可以帮忙吗?
由于
答案 0 :(得分:3)
匿名类型正确覆盖Equals
和GetHashCode
方法,但这些方法的实现又依赖于针对类型实现的Equals
和GetHashCode
方法为此对象定义的属性。
因此,例如,如果您定义这样的对象:
var anonym = new {A = 42, B = "XYZ"};
此匿名对象的Equals
和GetHashCode
的实施将调用Equals
类型的GetHashCode
和int
(因为属性A
类型为int
),类型为string
(因为属性B
的类型为string
)。
话虽如此,你想要实现的东西基本没用。实际上,如果您定义一个属性设置为对象s
的匿名类型,例如:
var myAnonym = new { s };
要正确地作为词典/哈希表中的键,必须正确定义对象GetHashCode
的{{1}}和Equals
方法。
但如果它们是,那么将对象包装在匿名类中有什么意义呢?你已经可以在词典中使用它了:-)