Equals 不应应用“is”¶
ID: cs/equals-uses-is
Kind: problem
Security severity:
Severity: warning
Precision: medium
Tags:
- reliability
- maintainability
Query suites:
- csharp-security-and-quality.qls
Equals
的函数签名将一个对象作为参数。 因此,通常要测试参数是否与调用 Equals
的对象属于同一类型。 这不应该使用 is
来完成,因为这种技术不会将参数限制为与对象完全相同的类型。 如果参数是对象类型的子类型,它不会返回 false。
作为该规则的一个例外,当您的类是密封类时,使用 is
是 可以接受的,因为那时不适用关于子类的考虑。 也就是说,即使在那时,最好也避免使用它,因为密封类有时以后可能会变成非密封类 - 尝试避免将来出现潜在问题是明智的。
建议¶
对参数调用 GetType()
,并将其与当前对象的类型进行比较。
示例¶
以下示例清楚地演示了使用 is
的问题。 该示例输出
b does equal d.
d does not equal b.
这种不对称性违反了 Equals 函数的约定。
class EqualsUsesIs
{
class BaseClass
{
public override bool Equals(object obj)
{
return obj is BaseClass;
}
}
class DClass : BaseClass
{
public override bool Equals(object obj)
{
return obj is DClass;
}
}
public static void Main(string[] args)
{
BaseClass b = new BaseClass();
DClass d = new DClass();
Console.WriteLine("b " + (b.Equals(d) ? "does" : "does not") + " equal d.");
Console.WriteLine("d " + (d.Equals(b) ? "does" : "does not") + " equal b.");
}
}