c#-检查复杂对象是否相等

时间:2020-06-06 07:46:22

标签: c#

相同类别的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);

    }

2 个答案:

答案 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. 两者的名字和章节都相同,即使顺序不一样

  1. 两者的名称相同,章节相同,顺序相同

如果使用选项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);
相关问题