2010-09-07 62 views
8

StyleCop有一條關於使用「this」的規則。前綴到呼叫類成員(SA1101)。C#StyleCop - 使用「this」。基類成員的前綴,如當前類成員或不是?

此規則適用於從其基類繼承的類的成員(例如方法)。

例子:

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? 
    } 
} 

我知道這只是爲了更好的可讀性。

+1

那麼,這是敲了StyleCop的方式嘗試了我的優先事項列表,然後。 – 2010-09-08 00:56:21

+0

@Jon Hanna:您可以配置哪些規則實際運行。我不會打折StyleCop,直到你看看它,並決定哪些規則對你很重要/有用。 – 2010-09-08 22:32:46

+0

@A。Karimi它不是爲了可讀性,實際上使用** base **會使代碼更具可讀性,它是爲了避免錯誤。該文檔有很好的示例和解釋http://stylecop.soyuz5.com/SA1100.html – 2013-05-16 17:02:47

回答

6

documentation for StyleCop Rule SA1101實際上提到了這一點:

每當代碼包含一個實例成員在本地類的或不與「前綴一個基類呼叫發生時該規則的違反這個。'。

(強調自己加上)。所以是的,規則要求每個對實例成員的訪問都需要this.,而不管該成員是在本地類還是從基類繼承。

+1

謝謝,它很感興趣!當你拒絕「這個」時,StyleCop不會顯示任何消息。基礎成員的前綴。 – 2010-09-08 06:43:08

-3

我喜歡使用base。 base.F1()爲你的情況。這可以防止意外地引用局部變量,並且是視覺提醒成員來自哪裏。

+0

這很好,但在這種情況下,我們會遇到stylecop中的另一個規則(SA1100:對GetItem的調用應該只使用'base。'前綴如果該項目在基類中聲明爲虛擬,並且在本地類中定義了覆蓋,否則以此爲前綴而不是基地) – 2010-09-07 22:47:50

+0

如果不是基本方法,使用「base」將是非常糟糕的做法你正在調用的當前虛擬方法。基礎方法可以是虛擬的,而你(或者你上面的層次結構中的其他人)可能想重寫它,然後你的基礎調用會調用錯誤的方法。 – Timwi 2010-09-07 23:18:11

+0

這是非常糟糕的做法。您應該僅使用base來指定您希望在該類中定義的基本方法*而不是*。在任何地方打電話都可以,但最好不要打。它很容易出錯,並會混淆查看代碼的其他人,因爲他們會將其理解爲合理使用,並且爲什麼他們無法找到覆蓋或隱藏方法而感到困惑。 – 2010-09-08 00:55:04

0

我認爲這是正確的,因爲規則適用於所有方法,無論它們是否在基礎上定義。就個人而言,我不是這個規則的巨大粉絲,所以我只是禁用它。

+0

我同意你的看法,但是有沒有像Stylecop這樣的人解釋這個問題? – 2010-09-07 22:54:27

5

如果你想爲對象繼承的規則,即使F1()實際上是宣佈BaseClass它是由ChildClass繼承所以它是有效的稱呼其爲this.F1()。這正是StyleCop告訴你要做的。通過在this前添加呼叫,您將調用該類的當前運行時實例的F1()實例方法變得明確無誤。

實際上,將其稱爲F1()this.F1()實際上是同義詞,但在使用前綴this時,含義/意圖變得更清晰。

根據F1()不是虛擬的並且在ChildClass中被覆蓋,您不應該在此使用base的前綴(即使它將被編譯)。使用base前綴的唯一原因是當您重寫了虛擬基類成員並希望從覆蓋成員中顯式調用該基類成員時。如果您確實使用base前綴而F1()爲虛擬,則所有實際上都會運行,直到您將F1()虛擬爲止並在ChildClass中添加覆蓋。此時,任何撥打base.F1()的電話將繼續撥打BaseClass.F1(),而不是ChildClass中的新覆蓋。