我需要比较两个对象,但在一次点击中比较它们的一些属性。 这不是为了排序,而是为了确认是否有任何变化;因为一个是旧保存的实例,第二个是新导入的同一个实例
我认为通过编写自定义比较器可以获得最佳效果。对于是IComparer
,还是IComparable
,还是tbh,我感到有点困惑。
感谢
NAT
答案 0 :(得分:9)
如果您的类只有单一的相等定义,则实际上不需要实现任何接口:只需覆盖Equals
方法即可。但是,最好的做法是实现IEquatable<T>
并明智地覆盖GetHashCode
(如果不覆盖哈希代码,当集合类,LINQ方法等将它用作pre时,相等性会出错。 - 平等的条件)。这是一个示例实现:
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<T>
实现。这是一个示例实现:
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);
答案 1 :(得分:0)
是的,你需要你的类型才能实现IComparable。 Here是一个如何做的示例。
答案 2 :(得分:0)
正如您所提到的,IComparable通常用于排序。
在这种情况下,您需要重载比较运算符:==
因为反向比较也应该有效,这意味着你还必须重载!=运算符。
当你重载==和! - 时,你也应该重写Equals和GetHashCode。
一本不错的C#书应该解释一下细节。
答案 3 :(得分:0)
实现IComparable接口的另一种方法是覆盖Equals和GetHashCode函数。
答案 4 :(得分:0)
这是关于你想如何进行比较操作的。您可以通过以下两种方式进行操作:
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是我的班级,我有一些业务需求。如果我想比较一些Foos,我使用FooComparer。对于您的情况,您可以从Compare方法返回已更改属性的数量。如果Compare方法返回0.则两个Foos相同。
正如我所说。这完全是你想要执行我认为的行动的方式。重写等式运算符也是很好的解决方案。实施IEqualityComparer<T>
是另一种解决方案。