CA1013:多載加號和減號運算子時必須一併多載等號比較運算子
型別名稱 |
OverloadOperatorEqualsOnOverloadingAddAndSubtract |
CheckId |
CA1013 |
分類 |
Microsoft.Design |
中斷變更 |
中斷 |
原因
公用或保護的型別會實作加法或減法運算,但不會實作等號比較運算子。
規則描述
使用如加法和減法的運算將型別的執行個體 (Instance) 加以組合時,您應該都會定義等號比較,以針對任兩個具有相同構成值的執行個體傳回 true。
您無法在等號比較運算子的多載實作中,使用預設的等號比較運算子, 這樣做會導致堆疊溢位 (Stack Overflow)。 若要實作等號比較運算子,請在實作中使用 Object.Equals 方法。 請參閱下列範例。
If (Object.ReferenceEquals(left, Nothing)) Then
Return Object.ReferenceEquals(right, Nothing)
Else
Return left.Equals(right)
End If
if (Object.ReferenceEquals(left, null))
return Object.ReferenceEquals(right, null);
return left.Equals(right);
如何修正違規
若要修正此規則的違規情形,請實作等號比較運算子,讓它在算術上會與加法和減法運算子一致。
隱藏警告的時機
當等號比較運算子的預設實作會提供型別的正確行為時,則您可以放心地隱藏這項規則的警告。
範例
下列範例會定義違反這項規則的型別 (BadAddableType)。 這個型別應該會實作等號比較運算子,以便在任兩個具有相同欄位值的執行個體相等時,使它的測試結果為 true。 型別 GoodAddableType 會顯示已更正的實作。 請注意,這個型別也會實作不等比較運算子並覆寫 Equals 以滿足其他規則。 完整實作也會實作 GetHashCode。
using System;
namespace DesignLibrary
{
public class BadAddableType
{
private int a, b;
public BadAddableType(int a, int b)
{
this.a = a;
this.b = b;
}
// Violates rule: OverrideOperatorEqualsOnOverridingAddAndSubtract.
public static BadAddableType operator +(BadAddableType a, BadAddableType b)
{
return new BadAddableType(a.a + b.a, a.b + b.b);
}
// Violates rule: OverrideOperatorEqualsOnOverridingAddAndSubtract.
public static BadAddableType operator -(BadAddableType a, BadAddableType b)
{
return new BadAddableType(a.a - b.a, a.b - b.b);
}
public override string ToString()
{
return String.Format("{{{0},{1}}}", a, b);
}
}
public class GoodAddableType
{
private int a, b;
public GoodAddableType(int a, int b)
{
this.a = a;
this.b = b;
}
// Satisfies rule: OverrideOperatorEqualsOnOverridingAddAndSubtract.
public static bool operator ==(GoodAddableType a, GoodAddableType b)
{
return (a.a == b.a && a.b == b.b);
}
// If you implement ==, you must implement !=.
public static bool operator !=(GoodAddableType a, GoodAddableType b)
{
return !(a==b);
}
// Equals should be consistent with operator ==.
public override bool Equals(Object obj)
{
GoodAddableType good = obj as GoodAddableType;
if (obj == null)
return false;
return this == good;
}
public static GoodAddableType operator +(GoodAddableType a, GoodAddableType b)
{
return new GoodAddableType(a.a + b.a, a.b + b.b);
}
public static GoodAddableType operator -(GoodAddableType a, GoodAddableType b)
{
return new GoodAddableType(a.a - b.a, a.b - b.b);
}
public override string ToString()
{
return String.Format("{{{0},{1}}}", a, b);
}
}
}
下列範例會使用本主題先前所定義的型別執行個體測試是否相等,以說明等號比較運算子的預設行為和正確行為。
using System;
namespace DesignLibrary
{
public class TestAddableTypes
{
public static void Main()
{
BadAddableType a = new BadAddableType(2,2);
BadAddableType b = new BadAddableType(2,2);
BadAddableType x = new BadAddableType(9,9);
GoodAddableType c = new GoodAddableType(3,3);
GoodAddableType d = new GoodAddableType(3,3);
GoodAddableType y = new GoodAddableType(9,9);
Console.WriteLine("Bad type: {0} {1} are equal? {2}", a,b, a.Equals(b)? "Yes":"No");
Console.WriteLine("Good type: {0} {1} are equal? {2}", c,d, c.Equals(d)? "Yes":"No");
Console.WriteLine("Good type: {0} {1} are == ? {2}", c,d, c==d? "Yes":"No");
Console.WriteLine("Bad type: {0} {1} are equal? {2}", a,x, a.Equals(x)? "Yes":"No");
Console.WriteLine("Good type: {0} {1} are == ? {2}", c,y, c==y? "Yes":"No");
}
}
}
這個範例產生下列輸出。
請參閱
參考
Guidelines for Implementing Equals and the Equality Operator (==)