【问题标题】:Are there any code analysis tools to detect the == operator when it's comparing specific types?在比较特定类型时是否有任何代码分析工具来检测 == 运算符?
【发布时间】:2012-01-11 16:32:50
【问题描述】:

在遗留代码库中,出于许多技术原因,我们正在将以前属于基类类型的参数替换为接口类型。例如:

public interface IDomainObject { int Id { get; } }

public abstract class BaseDomainObject : IDomainObject
{
    public int Id { get; protected set; }
    public override bool Equals(object obj)
    {
        var domainObj = obj as BaseDomainObject;
        return domainObj != null && Id.Equals(domainObj.Id);
    }
    public static bool operator ==(BaseDomainObject x, BaseDomainObject y)
    {
        return !ReferenceEquals(x, null) && !ReferenceEquals(y, null) && x.Equals(y);
    }
    public static bool operator !=(BaseDomainObject x, BaseDomainObject y)
    {
        return !(x == y);
    }
}

public class MyDomainObject : BaseDomainObject
{
    public MyDomainObject(int id) { Id = id; }
    ...
}

所以在代码中的任何地方,我们以前都会有一个 BaseDomainObject 类型的变量,现在我们有一个 IDomainObject 类型的变量。但是,我们遇到了 '==' 运算符的问题——它不适用于接口。对于所有接口类型,'==' 运算符只是回退到 ReferenceEquals()

下面的代码演示了这个问题:

    // Old style
    BaseDomainObject baseobj1A = new MyDomainObject(1);
    BaseDomainObject baseobj1B = new MyDomainObject(1);
    BaseDomainObject baseobj2 = new MyDomainObject(2);

    Assert.IsTrue(baseobj1A != baseobj2);
    Assert.IsTrue(baseobj1A == baseobj1B); // Succeeds

    // New style
    IDomainObject iobj1A = new MyDomainObject(1);
    IDomainObject iobj1B = new MyDomainObject(1);
    IDomainObject iobj2 = new MyDomainObject(2);

    Assert.IsTrue(iobj1A != iobj2);
    Assert.IsTrue(iobj1A == iobj1B); // Fails

回到使用基类不是一种选择——我们的接口是通用的协变体(类似于 IDomainObject),这对于我们需要的多态行为是必要的。理想情况下,我们只需将所有 '==' 替换为 .Equals()。但是,我们的代码库非常庞大,找到我们关心的所有 '==' 运算符将是一项艰巨的任务。

一个想法是我们可以编写一个 FxCop 规则,该规则将标记在“==”比较中使用的某个接口类型(即 IDomainObject)的所有出现的变量。但这不起作用——FxCop 不支持这一点。另一个想法是编写我们自己的代码分析工具来检查这种情况,但这会很耗时。

所以问题是,是否已经有某种代码分析工具可供我们用来查找这些“==”的出现?

【问题讨论】:

  • 您可以尝试使用 jetbrains.com 提供的 R# 之类的工具来查找所有类型的用法。它支持插件,您可以添加所需的功能。
  • 不,查找用法找不到它们。
  • 为什么说FxCop不支持这个?您是否真的尝试过创建自定义 FxCop 规则来查找针对您的目标接口实例的不适当的相等性验证?

标签: c# .net operators code-analysis


【解决方案1】:

您可以通过 ReSharper 使用自定义搜索模式来执行此类操作。

您也可以考虑以“老式方式”执行此操作。更改所有引用,然后修复编译错误。

【讨论】:

    【解决方案2】:

    如果 Visual Studio 的“查找所有引用”无法找到 == 特定实现的所有用法,我很确定 Resharper 的“查找用法”会毫无问题地找到它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-20
      • 2017-07-21
      • 1970-01-01
      • 2011-12-04
      • 2017-01-13
      • 2018-11-29
      • 2022-01-23
      相关资源
      最近更新 更多