CodeQL 文档

Equals 不应该应用“as”

ID: cs/equals-uses-as
Kind: problem
Security severity: 
Severity: warning
Precision: medium
Tags:
   - reliability
   - maintainability
Query suites:
   - csharp-security-and-quality.qls

点击查看 CodeQL 代码库中的查询

Equals 的函数签名将一个对象作为参数。 因此,通常会测试该参数是否与调用 Equals 的对象的类型相同。 这不应该使用 as 然后检查是否为 null 来完成,因为这种技术不会将参数限制为与对象完全相同的类型。 如果参数是对象类型的子类型,它不会返回 null。

作为该规则的例外,当您的类是密封类时,使用 as 是可以接受的,因为那时不适用关于子类的考虑。话虽如此,即使在那时也最好避免使用它,因为密封类有时会在以后变成非密封类 - 尽量避免将来出现潜在问题是明智的。

建议

在参数上调用 GetType() 并将其与当前对象的类型进行比较。

示例

以下示例清楚地演示了使用 as 的问题。 该示例输出

b does equal d.
d does not equal b.

这种不对称性违反了 Equals 函数的约定。

class EqualsUsesAs
{
    class BaseClass
    {
        public override bool Equals(object obj)
        {
            BaseClass objBase = obj as BaseClass;
            return objD != null;
        }
    }

    class DClass : BaseClass
    {
        public override bool Equals(object obj)
        {
            DClass objD = obj as DClass;
            return objD != null;
        }
    }

    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.");
    }
}

参考

  • ©GitHub 公司
  • 条款
  • 隐私