是否有任何代码分析工具在比较特定类型时检测==运算符?

时间:2012-01-11 16:32:50

标签: c# .net operators code-analysis

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

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< out T> ),这是我们需要的多态行为所必需的。理想情况下,我们只需要替换所有' =='使用 .Equals()。但是,我们的代码库非常庞大,并且找到了所有的' =='我们关心的运营商将是一项艰巨的任务。

有一种想法是我们可以编写一个FxCop规则来标记在' ==&#39中使用的某种接口类型的变量(即 IDomainObject )的所有出现;比较。但这并没有奏效--FxCop并不支持这一点。另一个想法是编写我们自己的代码分析工具,只检查这种情况,但这将是耗时的。

所以问题是,是否已经存在某种代码分析工具,我们可以用它来找到这些' =='出现?

2 个答案:

答案 0 :(得分:1)

您可以将自定义搜索模式与ReSharper一起使用来执行此类操作。

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

答案 1 :(得分:0)

如果Visual Studio“查找所有引用”无法找到==的具体实现的所有用法,我很确定Resharper“Find Usages”会发现它们没有问题。