检查两个对象实例以查看它们是否相同

发布于 2024-09-24 04:17:28 字数 199 浏览 1 评论 0原文

我需要比较两个对象,但一次比较它们的许多属性。 这不是为了排序,而是为了确认是否有任何变化;因为一个是旧的保存实例,第二个是同一事物的新导入实例,

我认为最好通过编写自定义比较器来实现。只是我有点困惑是否要执行 IComparer,或 IComparable,或者什么。

谢谢纳特

i need to compare two objects but compare a number of their properties in one hit.
this is not for sorting, but instead to confirm whether anything has changed; as one is the old saved instance, and the second is a newly imported instance of the same thing

i assume this is best served by writing a custom comparer. just am a bit confused as to whether to do IComparer, or IComparable, or what tbh.

thanks

nat

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

唠甜嗑 2024-10-01 04:17:28

如果您的类只有一个相等性定义,则实际上不需要实现任何接口:只需重写 Equals 方法即可。不过,最佳实践是实施 IEquatable 并明智地重写GetHashCode(如果不重写哈希码,当集合类、LINQ 方法等将其用作相等的前提条件时,相等性将出现错误)。这是一个示例实现:

public class Person : IEquatable<Person>
{
    public string Name { get; set; }
    public int Age { get; set; }

    public override int GetHashCode()
    {
        return (Name == null ? 0 : Name.GetHashCode()) ^ Age;
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as Person);
    }

    public bool Equals(Person other)
    {
        return other != null && other.Name == Name && other.Age == Age;
    }
}

这将允许您执行以下操作:

Person savedPerson = ...
Person importedPerson = ...

bool hasChanged = !savedPerson.Equals(importedPerson);

另一方面,如果您确实针对不同情况有许多不同的平等定义,那么您最好的选择是编写不同的 IEqualityComparer实现。这是一个示例实现:

public class AgeComparer : IEqualityComparer<Person>
{
    public bool Equals(Person x, Person y)
    {
        return (x == null || y == null) ? x == y : x.Age == y.Age;
    }

    public int GetHashCode(Person obj)
    {
        return obj == null ? 0 : obj.Age;
    }
}  

在这种情况下,检查将如下所示:

Person savedPerson = ...
Person importedPerson = ...
IEqualityComparer<Person> comparer = ...

bool hasChanged = !comparer.Equals(savedPerson, importedPerson);

If you only have a single definition of equality for your class, you don't really need to implement any interface: simply override the Equalsmethod. Best practice though, would be to implement IEquatable<T>and to override GetHashCode sensibly (if you don't override the hash-code, equality will misbehave when collection classes, LINQ methods etc. use it as a pre-condition for equality). Here's a sample implementation:

public class Person : IEquatable<Person>
{
    public string Name { get; set; }
    public int Age { get; set; }

    public override int GetHashCode()
    {
        return (Name == null ? 0 : Name.GetHashCode()) ^ Age;
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as Person);
    }

    public bool Equals(Person other)
    {
        return other != null && other.Name == Name && other.Age == Age;
    }
}

This will allow you to do:

Person savedPerson = ...
Person importedPerson = ...

bool hasChanged = !savedPerson.Equals(importedPerson);

If, on the other hand, you do have lots of different definitions of equality for different circumstances, your best bet would be to write up different IEqualityComparer<T>implementations. Here's a sample implementation:

public class AgeComparer : IEqualityComparer<Person>
{
    public bool Equals(Person x, Person y)
    {
        return (x == null || y == null) ? x == y : x.Age == y.Age;
    }

    public int GetHashCode(Person obj)
    {
        return obj == null ? 0 : obj.Age;
    }
}  

In this case, the check will look like:

Person savedPerson = ...
Person importedPerson = ...
IEqualityComparer<Person> comparer = ...

bool hasChanged = !comparer.Equals(savedPerson, importedPerson);
留一抹残留的笑 2024-10-01 04:17:28

正如您所提到的,IComparable 通常用于排序。

在这种情况下,您需要重载比较运算符: ==

因为反向比较也应该有效,这意味着您还必须重载 != 运算符。

当您重载 == 和 !- 时,您还需要覆盖 Equals 和 GetHashCode。

一本像样的 C# 书应该解释细节。

As you have alluded to IComparable is typically used for sorting.

In this case you would want to overload the comparison operator: ==

Because the reverse comparison should also be valid, this implies you must also overload the != operator.

When you overload == and !- you are also expected to override Equals and GetHashCode.

A decent C# book should explain the details.

实现 IComparable 接口的替代方法是重写 Equals 和 GetHashCode 函数。

An alternative to implementing the IComparable interface would be to override the Equals and GetHashCode functions.

許願樹丅啲祈禱 2024-10-01 04:17:28

这就是您想要如何执行比较操作。您可以通过两种方式进行操作:

public void Method()
{
    Foo p1 = new Foo();
    Foo p2 = new Foo();

    p1.CompareTo(p2);
    FooComparer c = new FooComparer();
    c.Compare(p1, p2);
}

class Foo : IComparable
{
    public int CompareTo(object obj)
    {
        throw new NotImplementedException();
    }
}

class FooComparer : IComparer<Foo>
{
    public int Compare(Foo x, Foo y)
    {
        throw new NotImplementedException();
    }
}

我更喜欢使用 IComparer 作为关注点分离。 Foo 是我的课程,我有一些业务需求。如果我想比较一些 Foo,我会使用 FooComparer。根据您的情况,您可以从 Compare 方法返回已更改属性的数量。如果 Compare 方法返回 0。那么两个 Foo 是相同的。

正如我所说。我认为这完全是你想要执行的操作的方式。重写相等运算符也是一个很好的解决方案。实现 IEqualityComparer 是另一种解决方案。

That is about how you want to perform compare operation. You can do the operation in both ways:

public void Method()
{
    Foo p1 = new Foo();
    Foo p2 = new Foo();

    p1.CompareTo(p2);
    FooComparer c = new FooComparer();
    c.Compare(p1, p2);
}

class Foo : IComparable
{
    public int CompareTo(object obj)
    {
        throw new NotImplementedException();
    }
}

class FooComparer : IComparer<Foo>
{
    public int Compare(Foo x, Foo y)
    {
        throw new NotImplementedException();
    }
}

I prefer using IComparer as seperation of concerns. Foo is my class, I have some busines needs on it. If I want to compare some Foos, I use FooComparer. For your situation you can return the number of changed properties from Compare method. If Compare method return 0. Then two Foos are same.

As I said. That is completely how you want to perform the action I think. Overriding Equality Operators are also good solution. Implementing IEqualityComparer<T> is another solution.

深海夜未眠 2024-10-01 04:17:28

是的,您将需要您的类型来实现 IComparable。 此处 是有关如何操作的示例。

Yes you will need your type to implement IComparable. Here is a sample on how to do it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文