我需要比較兩個對象,但比較一個命中中的一些屬性。 這不是爲了排序,而是爲了確認是否有任何改變;因爲一個是舊保存的實例,第二個是新導入的同一事物的實例檢查兩個對象實例以查看它們是否相同
我認爲最好通過編寫自定義比較器來達到這個目的。只是有點困惑至於是否要做IComparer
或IComparable
或什麼tbh。
感謝
NAT
我需要比較兩個對象,但比較一個命中中的一些屬性。 這不是爲了排序,而是爲了確認是否有任何改變;因爲一個是舊保存的實例,第二個是新導入的同一事物的實例檢查兩個對象實例以查看它們是否相同
我認爲最好通過編寫自定義比較器來達到這個目的。只是有點困惑至於是否要做IComparer
或IComparable
或什麼tbh。
感謝
NAT
如果您只有一個關於您班級的平等定義,您並不需要實現任何接口:只需覆蓋Equals
方法。最佳做法是實現IEquatable<T>
併合理地重寫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<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);
正如你所提到IComparable接口通常用於排序。
在這種情況下,你會想重載比較運算符:==
因爲反向比較也應該是有效的,這意味着你還必須重載=操作符!
當你重載==和! - 你也需要重寫Equals和GetHashCode。
一個體面的C#書應解釋的細節。
實現IComparable接口的替代方法是覆蓋Equals和GetHashCode函數。
這是關於如何執行比較操作。你可以以兩種方式運作:
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方法返回已更改屬性的數量。如果比較方法返回0.然後兩個Foos是相同的。
正如我所說。這完全是你想要執行我認爲的行動。壓倒一切的平等運營商也是很好的解決方案。實施IEqualityComparer<T>
是另一種解決方案。
這是一個很好的問題。所有的不同比較也讓我感到困惑。 – Greg 2010-09-21 13:27:43