Существуют ли инструменты анализа кода для обнаружения оператора == при сравнении определенных типов? - PullRequest
1 голос
/ 11 января 2012

В устаревшей кодовой базе по многим техническим причинам мы заменяем параметры, которые ранее имели тип базового класса, на тип интерфейса.Например:

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 не поддерживает это.Другая мысль заключалась в том, чтобы написать наш собственный инструмент для анализа кода, который просто проверяет этот случай, но это отнимает много времени.

Итак, вопрос в том, существует ли уже какой-то инструмент анализа кода, который мы могли бы использовать, чтобы найти эти вхождения "=="?

Ответы [ 2 ]

1 голос
/ 11 января 2012

Вы можете использовать пользовательские шаблоны поиска с ReSharper, чтобы делать такие вещи.

Вы также можете подумать о том, чтобы сделать это «по старинке».Измените все ссылки, затем исправьте ошибки компиляции.

0 голосов
/ 11 января 2012

Если в Visual Studio «Найти все ссылки» не удается найти все варианты использования конкретной реализации ==, я почти уверен, что «Поиск использования» Решарпера найдет их без проблем.

...