C# 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
@А. Karimi не е за четливост, всъщност използването на base ще направи кода по-четлив, то е за избягване на грешки. Документацията има добра проба и обяснение stylecop.soyuz5.com/SA1100.html   -  person Marco Medrano    schedule 16.05.2013


Отговори (4)


В документацията за StyleCop Rule 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() instance на текущия екземпляр по време на изпълнение на класа.

Всъщност наричането му като 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.“ само ако елементът е деклариран виртуален в базовия клас и е дефинирано заместване в локалния клас. В противен случай , префикс на повикването с това, а не с база) - person Amir Karimi; 08.09.2010
comment
Използването на „base“ би било наистина лоша практика, ако това не е основният метод на текущия виртуален метод, който извиквате. Базовият метод може да бъде направен виртуален и вие (или някой друг в йерархията над вас) може да искате да го замените и тогава вашето основно извикване ще извика грешен метод. - person Timwi; 08.09.2010
comment
Това е наистина лоша практика. Трябва да използвате base само за да посочите, че искате основния метод вместо такъв, дефиниран в този клас. Да го извикате навсякъде, освен в надскачане или скриване, в най-добрия случай е странно. Склонен е към грешки и би объркал другите, които гледат кода, тъй като биха го интерпретирали като използван разумно и биха се объркали защо не могат да намерят метода за преодоляване или скриване. - person Jon Hanna; 08.09.2010