Что стоит за правилом FXCop CA1061 «Не скрывать методы базового класса»? - PullRequest
0 голосов
/ 06 июля 2010

Почему правило FxCop CA1061 является плохой идеей?

Документы утверждают, что это правило не должно подавляться.Если у меня есть такой класс:

public class Set<T>
{    List<T> m_backingList;

     public bool Contains(T value)
     {
         return m_backingList.Contains(value);
     }
}  

, тогда я добавляю конкретную реализацию, подобную этой:

public class CaseInsensitiveSet : Set<String>
{
    public bool Contains(object value)
    {
         string stringValue  = value as string;
         if (stringValue == null)
             return false;
         return base.Contains(stringValue);
    }
}

, FxCop жалуется, но я не уверен, почему это так плохоидея.Есть ли какие-то проблемы, которые я не вижу в этой реализации?

Ответы [ 3 ]

4 голосов
/ 06 июля 2010

Правило гласит, почему вы получаете сообщение:

Метод в базовом типе скрыт методом с одинаковым именем в производном типе, когда сигнатура параметра производного метода отличается толькопо типам, которые являются более слабыми производными, чем соответствующие типы в сигнатуре параметра базового метода.

В вашем дочернем классе метод Contains принимает object, который имеет более слабую типизацию, чем string и, следовательно, скрывает родителя.

Причина, по которой вы получаете предупреждение от FxCop, заключается в том, что это может быть не преднамеренный выбор дизайна (поскольку вы ничего не отменяете или не используете ключевое слово new).

Даже если это намеренный выбор дизайна, я бы сказал, что это не обязательно хороший выбор.Если вы уже знаете, что коллекция будет содержать строки и ничего больше, зачем вам предоставлять метод Contains, который принимает что-то отличное от string?Может показаться, что вы добавляете гибкость в дизайн, но, в конце концов, вы действительно только запутаете других разработчиков.

Существуют также другие варианты именования вместо вызова метода Contains, которые не скрывают (намеренно или нет) метод базового содержимого.

0 голосов
/ 06 июля 2010

Задайте себе вопрос: хочу ли я, чтобы пользователи могли вызывать метод базового класса для экземпляра производного класса. Если ответ «да»: не скрывайте базовый метод, так как это сделает его более громоздким. Если ответ отрицательный: не наследуйте этот класс, иначе они все равно могут получить доступ к базовому методу, приведя объект к базовому классу.

0 голосов
/ 06 июля 2010

http://msdn.microsoft.com/en-us/library/ms182143(VS.80).aspx

Метод в базовом типе скрыт метод с таким же именем в производный тип, когда параметр подпись производного метода отличается только типами, которые более слабо выведен, чем соответствующий вводит в сигнатуру параметра базовый метод.

EDIT

По сути, вы скрываете базовый метод (public bool Contains in Set), который теперь никогда не будет запускаться вместо предпочтения производного метода. Но производный метод определен слабее, чем базовый, поэтому существуют ситуации, когда базовый метод является предпочтительным.

...