使用IEquatable处理LINQ Distinct中的对象相等性
LINQ的Distinct
方法旨在根据对象的相等性识别唯一对象。但是,对于自定义对象,它可能并不总是按预期工作。
在提供的示例中,Distinct
方法未能识别名称相同的两个Author
对象为重复项。这是因为LINQ根据对象的引用地址而不是其属性值将对象视为不同的。
为了解决这个问题,可以在Author
类中实现IEquatable
接口。通过重写Equals
方法,您可以定义自定义逻辑,以根据属性值FirstName
和LastName
确定相等性。下面的实现检查两个字段中的匹配值以确定相等性:
<code class="language-csharp">public class Author : IEquatable<Author> { public string FirstName { get; set; } public string LastName { get; set; } public bool Equals(Author other) { if (FirstName == other?.FirstName && LastName == other?.LastName) return true; return false; } // 为保持一致性而重写GetHashCode public override int GetHashCode() { return (FirstName?.GetHashCode() ?? 0) ^ (LastName?.GetHashCode() ?? 0); } }</code>
用法:
应用此自定义实现解决了Distinct
的问题。修改后的代码正确地识别了重复的Author
对象,并从结果中删除了其中一个:
<code class="language-csharp">using System.Collections.Generic; using System.Linq; class Program { static void Main(string[] args) { // 使用重复作者初始化书籍列表 List<Book> books = new List<Book> { new Book { Name = "C# in Depth", Authors = new List<Author> { new Author { FirstName = "Jon", LastName = "Skeet" }, new Author { FirstName = "Jon", LastName = "Skeet" }, } }, // ... }; // 选择作者,应用Distinct,并打印 var temp = books.SelectMany(book => book.Authors).Distinct(); foreach (var author in temp) { Console.WriteLine($"{author.FirstName} {author.LastName}"); } Console.Read(); } }</code>
结论:
实现IEquatable
并重写Equals
方法允许在LINQ操作中自定义对象相等性的定义。这确保了Distinct
方法根据其属性而不是引用地址正确处理自定义对象。
请注意,代码示例中已对GetHashCode
方法进行了改进,以确保与Equals
方法的一致性,并使用了null-conditional operator (?.) 来处理可能为null的属性。 这避免了潜在的NullReferenceException
异常。
以上是如何确保 LINQ 的 Distinct 方法与自定义对象正确的对象相等?的详细内容。更多信息请关注PHP中文网其他相关文章!