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 (==)