CodeQL 文档

对 operator== 的递归调用

ID: cs/recursive-operator-equals-call
Kind: problem
Security severity: 
Severity: error
Precision: medium
Tags:
   - reliability
   - maintainability
Query suites:
   - csharp-security-and-quality.qls

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

编写 operator== 时,通常需要检查操作数是否为空或检查两个操作数是否引用同一个对象。尝试使用 == 来完成此操作将不起作用,因为它只会调用正在定义的重写的 operator==

建议

有两种建议的方法可以解决此问题。最简洁的方法是简单地将对 operator== 的调用替换为对 ReferenceEquals 的调用(请参阅下面的代码)。作为一种不太可取的替代方法,也可以简单地将参数强制转换为 object

示例

在此示例中,== 重载将不断调用自身,以将传递给它的初始参数与 null 进行比较。

class Year
{
    private int year;
    private bool bc;

    public Year(int i)
    {
        year = Math.Abs(i);
        bc = i < 0;
    }

    public static bool operator ==(Year lhs, Year rhs)
    {
        // Both of these checks against null call operator== recursively.
        // They were probably intended to be checks for reference equality.
        if (lhs == null || rhs == null)
        {
            return false;
        }

        return lhs.year == rhs.year && lhs.bc == rhs.bc;
    }

    public static bool operator !=(Year lhs, Year rhs)
    {
        return !(lhs == rhs);
    }
}

最佳解决方法是改用 ReferenceEquals 方法。

class Year
{
    private int year;
    private bool bc;

    public Year(int i)
    {
        year = Math.Abs(i);
        bc = i < 0;
    }

    public static bool operator ==(Year lhs, Year rhs)
    {
        // Either of these alternative approaches works.
        if (ReferenceEquals(lhs, null) || (object)rhs == null)
        {
            return false;
        }

        return lhs.year == rhs.year && lhs.bc == rhs.bc;
    }

    public static bool operator !=(Year lhs, Year rhs)
    {
        return !(lhs == rhs);
    }
}

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私