LINQ Distinct() 方法在自定义对象中的异常行为
在使用 LINQ to Objects 时,Distinct()
方法在处理自定义对象时可能不会总是产生预期的结果。默认情况下,LINQ 只考虑引用进行唯一性比较。
在提供的代码示例中,您有一个 Book
对象列表,每个对象都包含一个 Author
对象列表。当您使用 SelectMany()
将 Authors
集合展平为单个列表,然后调用 Distinct()
时,您期望它只返回唯一的作者。但是,您观察到同一个作者 (Jon Skeet) 出现了两次。
问题在于,LINQ 中的 Distinct()
方法默认情况下基于对象引用进行操作。由于您的列表中存在两个单独的 Author
对象,即使它们具有相同的值,LINQ 也会认为它们是不同的。为了克服这个问题,您需要提供一个自定义的相等性实现来明确定义如何比较对象的唯一性。
重写 Equals 方法
正如您在问题中所建议的,您可以重写 Author
类中的 Equals()
方法来指定相等性条件。但是,您当前的实现总是返回 true
,使得所有作者看起来都是相等的。
实现 IEquatable 接口
更合适的方法是在您的类中实现 IEquatable<Author>
接口。此接口允许您定义自定义相等性比较器。在您的情况下,您可以根据作者的姓名进行比较:
<code class="language-csharp">public class Author : IEquatable<Author> { public bool Equals(Author other) { return FirstName == other.FirstName && LastName == other.LastName; } }</code>
在 LINQ 查询中重用作者
实现 IEquatable<Author>
后,您可以使用它来改进 Distinct()
方法的行为。修改您的 LINQ 查询如下:
<code class="language-csharp">var temp = books.SelectMany(book => book.Authors).DistinctBy(a => new { a.FirstName, a.LastName });</code>
通过使用 DistinctBy()
和一个自定义 lambda 表达式来定义 FirstName
和 LastName
的元组,您可以明确指定如何比较作者的唯一性。
通过遵循这些步骤,您可以确保 Distinct()
方法正确识别并消除重复的作者,同时保留它们的值。
以上是为什么 LINQ Distinct() 对于自定义对象不能按预期工作?的详细内容。更多信息请关注PHP中文网其他相关文章!