此代码返回不同的值.然而,我想要的是返回一个强类型集合,而不是匿名类型
本文关键字:返回 集合 强类型 一个 类型 代码 然而 我想要 | 更新日期: 2023-09-27 18:08:06
我有以下代码:
var foo = (from data in pivotedData.AsEnumerable()
select new
{
Group = data.Field<string>("Group_Number"),
Study = data.Field<string>("Study_Name")
}).Distinct();
正如预期的那样,这将返回不同的值。然而,我想要的是返回一个强类型集合,而不是匿名类型,所以当我这样做时:
var foo = (from data in pivotedData.AsEnumerable()
select new BarObject
{
Group = data.Field<string>("Group_Number"),
Study = data.Field<string>("Study_Name")
}).Distinct();
这不会返回不同的值,而是返回所有值。有没有一种方法可以用实际的物体做到这一点?
要使Distinct()
(和许多其他LINQ功能(工作,被比较的类(在您的示例中为BarObject
(必须实现Equals()
和GetHashCode()
,或者提供一个单独的IEqualityComparer<T>
作为Distinct()
的参数。
许多LINQ方法利用GetHashCode()
来提高性能,因为在内部它们会使用Set<T>
之类的东西来保存唯一项,后者使用哈希来进行O(1(查找。此外,GetHashCode()
可以很快告诉您两个对象是否可以等价,以及哪些对象绝对不等价——当然,只要GetHashCode()
得到了正确的实现。
因此,为了完整性,您应该让您打算在LINQ中比较的所有类实现Equals()
和GetHashCode()
,或者创建一个单独的IEqualityComparer<T>
实现。
按照dlev的建议执行或使用:
var foo = (from data in pivotedData.AsEnumerable()
select new BarObject
{
Group = data.Field<string>("Group_Number"),
Study = data.Field<string>("Study_Name")
}).GroupBy(x=>x.Group).Select(x=>x.FirstOrDefault())
查看此以了解更多信息http://blog.jordanterrell.com/post/LINQ-Distinct((-does-not-work-as-expected.aspx
您需要为BarObject
重写Equals
和GetHashCode
,因为除非您提供了Equals
和GetHashCode
的重写(这是Enumerable.Distinct<BarObject>(this IEnumerable<BarObject> source)
使用的(,否则EqualityComparer.Default<BarObject>
是引用相等。或者,您可以将IEqualityComparer<BarObject>
传递给Enumerable.Distinct<BarObject>(this IEnumerable<BarObject>, IEqualityComparer<BarObject>)
。
看起来Distinct
无法比较您的BarObject
对象。因此,它比较了它们的参考文献,当然它们彼此不同,即使它们的内容相同。
因此,要么覆盖Equals
方法,要么为Distinct
提供自定义EqualityComparer。当您实现Equals
时,请记住覆盖GetHashCode
,否则,如果您将对象作为关键字(例如HashSet<BarObject>
(放入字典或哈希表中,会产生奇怪的结果。Distinct内部可能使用了一个哈希集(不确切(。
以下是GetHashCode
的一些良好实践。
您想要为Distinct((使用另一个重载,该重载需要一个比较器。然后,您可以实现自己的IEqualityComparer<条形图对象>。
试试这个:
var foo = (from data in pivotedData.AsEnumerable().Distinct()
select new BarObject
{
Group = data.Field<string>("Group_Number"),
Study = data.Field<string>("Study_Name")
});
应该像一样简单
var foo = (from data in pivotedData.AsEnumerable()
select new
{
Group = data.Field<string>("Group_Number"),
Study = data.Field<string>("Study_Name")
}).Distinct().Select(x => new BarObject {
Group = x.Group,
Study = x.Study
});