相同类别的2个对象具有相同的信息,仅差异列表的索引具有互换的数据。 我正在检查Linq Intersect和Except运算符,如何从它们中得到预期的结果?我有更复杂的对象,其中包含列表。 以下有关调试的代码从不涉足运算符方法。可能是我在这里犯了一个错误。 谁能指导我。
样书课
class Book
{
public List<Chapter> Chapters { get; set; }
public string Name { get; set; }
}
class Chapter
{
public string name { get; set; }
public List<Page> Pages { get; set; }
}
class Page
{
public int number { get; set; }
}
我已经使用iEqualityComparer创建了帮助器类
class ChapterComparer : IEqualityComparer<Chapter>
{
public bool Equals(Chapter x, Chapter y)
{
if (string.Equals(x.name, y.name, StringComparison.OrdinalIgnoreCase))
{
return true;
}
return false;
}
public int GetHashCode(Chapter obj)
{
return obj.name.GetHashCode();
}
}
class BookComprarer : IEqualityComparer<Book>
{
public bool Equals(Book x, Book y)
{
if (string.Equals(x.Name, y.Name, StringComparison.OrdinalIgnoreCase))
{
if (x.Chapters.Except(y.Chapters, new ChapterComparer()).Any() != false)
{
return true;
}
}
return false;
}
public int GetHashCode(Book obj)
{
return obj.Name.GetHashCode();
}
}
此处我生成图书数据
private Book GetBookUpdate()
{
return new Book()
{
Name = "Book 1",
Chapters = new List<Chapter>()
{
new Chapter()
{
name = "Story 1",
Pages = new List<Page>()
{
new Page()
{
number = 2
},
new Page()
{
number = 3
},
new Page()
{
number = 4
}
}
},
new Chapter()
{
name = "Story 2",
Pages = new List<Page>()
{
new Page()
{
number = 5
},
new Page()
{
number = 6
},
new Page()
{
number = 7
}
}
}
}
};
}
private Book GetLocalBook()
{
return new Book()
{
Name = "Book 1",
Chapters = new List<Chapter>()
{
new Chapter()
{
name = "Story 2",
Pages = new List<Page>()
{
new Page()
{
number = 5
},
new Page()
{
number = 6
},
new Page()
{
number = 7
}
}
},
new Chapter()
{
name = "Story 1",
Pages = new List<Page>()
{
new Page()
{
number = 2
},
new Page()
{
number = 3
},
new Page()
{
number = 4
}
}
}
}
};
}
}
我在这里创建了比较方法。
public void TestMethod1()
{
Book r1 = GetLocalBook();
Book r2 = GetBookUpdate();
var d = r1.Equals(r2);
}
答案 0 :(得分:0)
这里有两个问题:
当书x和y具有相同的章节时,x.Chapters.Except(y.Chaters,...)。Any()将为false(x没有y以外的任何章节),因此条件应该是
if (x.Chapters.Except(y.Chapters, new ChapterComparer()).Any() == false)
此外,在比较图书时,您需要使用BookComparer:
var d = new BookComprarer().Equals(r1, r2);
答案 1 :(得分:0)
如果使用IEqualityComparer,则不能仅使用Equals()。另外,您从Microsoft recommends继承的EqualityComprarer也是这样:
我们建议您从EqualityComparer类派生而不是实现IEqualityComparer接口
然后,您必须问自己,一本书等于另一本书意味着什么。如果可以是:
或
如果使用选项1,则只需对列表中的项目(using OrderBy)进行排序,然后再进行比较(使用Linq method SequenceEqual):
class BookComprarer : EqualityComparer<Book>
{
public override bool Equals(Book b1, Book b2)
{
if (b1 == null || b2 == null)
return false;
if (!string.Equals(b1.Name, b2.Name, StringComparison.OrdinalIgnoreCase))
return false;
ChapterComparer cmp = new ChapterComparer();
//If you go with option 2, just use bx.Chapters;
var c1 = b1.Chapters.OrderBy(x => x.Name.ToLower()); //ToLower so we ignore case
var c2 = b2.Chapters.OrderBy(x => x.Name.ToLower());
return c1.SequenceEquals(c2, cmp);
}
public override int GetHashCode(Book obj)
{
return obj.Name.GetHashCode();
}
}
无论是否要在比较中包括页面,“章节比较”都一样。
然后,您需要比较两本书:
BookComparer cmp = new BoolComparer();
Book b1 = GetLocalBook();
Book b2 = GetBookUpdate();
bool areBookEquals = cmp.Equals(b1, b2);