Это ложное срабатывание из-за незначительной ошибки в самом правиле. При попытке выяснить, реализует ли класс повторно IDisposable (после выяснения, что существует реализация базового класса, которая может быть переопределена), он только проверяет, включают ли интерфейсы класса IDisposable. К сожалению, список интерфейсов, который отображается в метаданных сборки, включает «разнесенный» список интерфейсов, включая любые интерфейсы, унаследованные через интерфейсы, которые класс явно реализует в исходном коде C #. Это означает, что FxCop видит объявление, которое выглядит следующим образом для вашего класса Functionality:
public class Functionality : Reusable, IFunctionality, IDisposable
{
...
}
Учитывая это представление метаданных, правило ImplementIDisposableCorrectly должно быть немного более интеллектуальным о том, как оно пытается определить, действительно ли класс повторно реализует IDisposable (например, путем поиска явной реализации Dispose (), если базовый класс имеет переопределенный Dispose (bool)). Однако, учитывая, что правило этого не делает, ваш лучший подход - подавлять ложные срабатывания.
Кстати, я бы настоятельно рекомендовал рассмотреть возможность использования SuppressMessageAttribute для подавления ложных срабатываний вместо вашего текущего подхода к условной компиляции. e.g.:
[SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly",
Justification = "False positive. IDisposable is inherited via IFunctionality. See /5218650/analiz-koda-ca1063-srabatyvaet-pri-vyvode-iz-idisposable-i-obespechenii-realizatsii-v-bazovom-klasse for details.")]
public class Functionality : Reusable, IFunctionality
{
...
}
Кроме того, вы можете серьезно подумать об избавлении от финализатора ...