此代码返回不同的值.然而,我想要的是返回一个强类型集合,而不是匿名类型

本文关键字:返回 集合 强类型 一个 类型 代码 然而 我想要 | 更新日期: 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重写EqualsGetHashCode,因为除非您提供了EqualsGetHashCode的重写(这是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
               });