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" }, } }, new Book { Name="LINQ in Action", Authors = new List<Author> { new Author { FirstName = "Fabrice", LastName="Marguerie" }, new Author { FirstName = "Steve", LastName="Eichert" }, new Author { FirstName = "Jim", LastName="Wooley" }, } }, }; var temp = books.SelectMany(book => book.Authors).Distinct(); foreach (var author in temp) { Console.WriteLine(author.FirstName + " " + author.LastName); } Console.Read(); } } public class Book { public string Name { get; set; } public List<Author> Authors { get; set; } } public class Author { public string FirstName { get; set; } public string LastName { get; set; } public override bool Equals(object obj) { return true; //if (obj.GetType() != typeof(Author)) return false; //else return ((Author)obj).FirstName == this.FirstName && ((Author)obj).FirstName == this.LastName; } }
这基于“ LINQ in Action”中的示例。清单4.16
这将打印两次Jon Skeet。为什么?我什至尝试在Author类中重写Equals方法。仍然不同似乎没有用。我想念什么?
编辑:我也添加了==和!=运算符重载。仍然没有帮助。
public static bool operator ==(Author a, Author b) { return true; } public static bool operator !=(Author a, Author b) { return false; }
对于自定义对象,LINQ Distinct不是那么聪明。
它所做的只是查看您的列表,并看到它具有两个不同的对象(它不在乎它们的成员字段具有相同的值)。
一个解决办法是实现IEquatable接口如图所示这里。
如果您像这样修改Author类,它应该可以工作。
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; } public override int GetHashCode() { int hashFirstName = FirstName == null ? 0 : FirstName.GetHashCode(); int hashLastName = LastName == null ? 0 : LastName.GetHashCode(); return hashFirstName ^ hashLastName; } }
尝试作为DotNetFiddle