對於引用平等,我使用object.ReferenceEquals
如您所說,儘管您也可以將引用轉換爲對象並進行比較(只要它們是引用類型)。
對於2和3,它真的取決於開發人員想要什麼,如果他們想要將相等定義爲身份或值相等。通常,我喜歡將Equals()保留爲值相等,然後爲外部比較器提供身份相等。
大多數比較項目的方法都讓您能夠傳入自定義比較器,這就是我通常在任何自定義相等比較器(如身份)中傳遞的位置,但這就是我。
正如我所說,這是我的典型用法,我也構造的對象模型在那裏我只考慮屬性的子集來表示身份和其他人不比較。
您可以隨時創建一個非常簡單的ProjectionComparer,它可以接受任何類型的數據並根據投影創建一個比較器,使得在需要的地方傳遞自定義比較器以識別標識等非常容易,並且只需等待Equals()方法值。
而且,通常情況下,我個人不超載==除非我寫的是需要典型的比較操作的值類型,因爲運算符重載和超載怎麼都沒有覆蓋這麼大的混亂。
但同樣,這只是我的:-)
UPDATE意見這裏是我的投影比較器,你可以找到許多其他的實現,當然,不過這一次很適合我,它實現了兩個EqualityComparer<TCompare>
(支持bool Equals(T, T)
和int GetHashCode(T)
和IComparer<T>
支持Compare(T, T)
):
public sealed class ProjectionComparer<TCompare, TProjected> : EqualityComparer<TCompare>, IComparer<TCompare>
{
private readonly Func<TCompare, TProjected> _projection;
// construct with the projection
public ProjectionComparer(Func<TCompare, TProjected> projection)
{
if (projection == null)
{
throw new ArgumentNullException("projection");
}
_projection = projection;
}
// Compares objects, if either object is null, use standard null rules
// for compare, then compare projection of each if both not null.
public int Compare(TCompare left, TCompare right)
{
// if both same object or both null, return zero automatically
if (ReferenceEquals(left, right))
{
return 0;
}
// can only happen if left null and right not null
if (left == null)
{
return -1;
}
// can only happen if right null and left non-null
if (right == null)
{
return 1;
}
// otherwise compare the projections
return Comparer<TProjected>.Default.Compare(_projection(left), _projection(right));
}
// Equals method that checks for null objects and then checks projection
public override bool Equals(TCompare left, TCompare right)
{
// why bother to extract if they refer to same object...
if (ReferenceEquals(left, right))
{
return true;
}
// if either is null, no sense checking either (both are null is handled by ReferenceEquals())
if (left == null || right == null)
{
return false;
}
return Equals(_projection(left), _projection(right));
}
// GetHashCode method that gets hash code of the projection result
public override int GetHashCode(TCompare obj)
{
// unlike Equals, GetHashCode() should never be called on a null object
if (obj == null)
{
throw new ArgumentNullException("obj");
}
var key = _projection(obj);
// I decided since obj is non-null, i'd return zero if key was null.
return key == null ? 0 : key.GetHashCode();
}
// Factory method to generate the comparer for the projection using type
public static ProjectionComparer<TCompare, TProjected> Create<TCompare,
TProjected>(Func<TCompare, TProjected> projection)
{
return new ProjectionComparer<TCompare, TProjected>(projection);
}
}
這使你可以做這樣的事情:
List<Employee> emp = ...;
// sort by ID
emp.Sort(ProjectionComparer.Create((Employee e) => e.ID));
// sort by name
emp.Sort(ProjectionComparer.Create((Employee e) => e.Name));
到目前爲止,我發現的一切似乎都指向WPF,使用'Equals()'而不是'ReferenceEquals()'或'=='來執行相等操作。 [鏈接1](http://www.lhotka.net/weblog/DataRefreshInWPF.aspx)[鏈接2](http://kentb.blogspot.com/2007/03/beware-datacontext-and-equals.html) 。可能是因爲你的同事改變了類的'Equals()'方法以單向工作,改變了數據,期望數據綁定更新,並且它不是因爲Equals()仍然返回true? –
謝謝,我認爲第二個鏈接的開頭段落完美地解釋了它(並且比我的同事更好!)。 – SonOfPirate