С# StyleCop — использование этого. префикс для членов базового класса, таких как текущие члены класса или нет?

В StyleCop есть правило использования «этого». префикс для вызова членов класса (SA1101).

Справедливо ли это правило для члена (например, метода) класса, унаследованного от его базового класса.

Пример:

class BaseClass
{
    protected void F1()
    {
        ...
    }
}    

class ChildClass : BaseClass
{
    protected void F2()
    {
        ...
    }

    protected void F3()
    {
        this.F2(); // This is correct acording to SA1101

        // F1 is a member of base class and if I dont put this prefix, stylecop will not show any message.
        this.F1(); // Is this correct?
        F1();      // Or this?
    }
}

Я знаю, что это просто для лучшей читабельности.


person Amir Karimi    schedule 07.09.2010    source источник
comment
Что ж, значит, это выбило меня из списка приоритетов, чтобы попробовать StyleCop.   -  person Jon Hanna    schedule 08.09.2010
comment
@Jon Hanna: Вы можете настроить, какие правила действительно выполняются. Я бы не стал сбрасывать со счетов StyleCop, пока вы не посмотрите на него и не решите, какие правила важны/полезны для вас.   -  person Scott Dorman    schedule 09.09.2010
comment
@А. Карими, это не для удобочитаемости, на самом деле использование base сделало бы код более читабельным, это чтобы избежать ошибок. В документации есть хороший образец и объяснение stylecop.soyuz5.com/SA1100.html   -  person Marco Medrano    schedule 16.05.2013


Ответы (4)


В документации по правилу StyleCop SA1101 упоминается следующее:

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

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

person Timwi    schedule 07.09.2010
comment
Спасибо, интересно! StyleCop не будет показывать никаких сообщений, если вы забыли об этом. префикс для базовых членов. - person Amir Karimi; 08.09.2010

Если вы думаете о правилах наследования объектов, даже если F1() на самом деле объявлено BaseClass, оно наследуется ChildClass, поэтому его можно назвать this.F1(). Это то, что StyleCop говорит вам делать. Префикс вызова с префиксом this становится недвусмысленным, что вы вызываете метод F1() экземпляра текущего экземпляра класса во время выполнения.

На самом деле, называть его как F1() или this.F1() на самом деле синонимы, но смысл/намерение становится более ясным при использовании префикса this.

Вы вообще не должны использовать здесь префикс base (даже если он скомпилируется), потому что F1() не является виртуальным и переопределяется в ChildClass. Единственная причина использования префикса base — это когда вы переопределили член виртуального базового класса и хотите явно вызвать этот член базового класса из переопределяющего члена. Если бы вы действительно использовали префикс base без виртуального F1(), все было бы на самом деле работать, пока вы не сделаете F1() виртуальным и не добавите переопределение в ChildClass. В этот момент любые вызовы base.F1() будут продолжать вызывать BaseClass.F1(), а не новое переопределение в ChildClass.

person Scott Dorman    schedule 07.09.2010

Я считаю, что это правильно, поскольку правило выполняется для всех методов, независимо от того, определены они на базе или нет. Лично я не большой поклонник этого правила, поэтому просто отключил его.

person Nathan    schedule 07.09.2010
comment
Я согласен с вами, но есть ли кто-нибудь или что-то вроде stylecop, которые объясняют это? - person Amir Karimi; 08.09.2010

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

person jwetzel1492    schedule 07.09.2010
comment
Это хорошо, но в этом случае мы столкнемся с другим правилом в stylecop (SA1100: вызов GetItem должен использовать префикс base. только в том случае, если элемент объявлен виртуальным в базовом классе, а переопределение определено в локальном классе. В противном случае , добавьте к вызову префикс this, а не base) - person Amir Karimi; 08.09.2010
comment
Использование «базы» было бы очень плохой практикой, если бы это не был базовый метод текущего виртуального метода, который вы вызываете. Базовый метод может быть сделан виртуальным, и вы (или кто-то другой в иерархии выше вас) может захотеть переопределить его, и тогда ваш базовый вызов вызовет неправильный метод. - person Timwi; 08.09.2010
comment
Это действительно плохая практика. Вы должны использовать base только для того, чтобы указать, что вам нужен базовый метод вместо метода, определенного в этом классе. Вызывать его где угодно, кроме как в over-ride или hider, в лучшем случае изворотливо. Он склонен к ошибкам и может сбить с толку других, смотрящих на код, поскольку они интерпретируют его как разумно используемый и будут сбиты с толку тем, почему они не могут найти метод переопределения или скрытия. - person Jon Hanna; 08.09.2010