2012-05-08 55 views
0

我想在另一個類中調用一個靜態變量的getter。誰能告訴我,爲什麼這個工程:這兩個屬性實現之間的區別?

protected static SymTab _symTab; 

public SymTab symTab 
{ 
    get{return _symTab;} 
    set{_symTab = value;} 
} 

,這並不:

public static SymTab symTab {get; protected set;} 
+1

什麼不行?你是否試圖將它稱爲實例方法? – leppie

+0

是的,最終成爲問題。糟糕的Java習慣。 –

回答

4

第一個版本有一個實例屬性獲取/設置一個靜態變量。

第二個版本有一個靜態屬性獲取/設置一個靜態變量。 (setter也受到保護,但這似乎不是你的直接問題。)

我強烈勸阻第一種形式 - 實例屬性應反映有關該實例的內容;您不希望在一個實例上設置屬性來更改其他實例的屬性值。

隨着第二種形式,你可以使用:

SymTab currentTab = TypeName.symTab; 

代替:

SymTab currentTab = someVariable.symTab; 

此外,我想指出:

  • 屬性名symTab違反.NET命名約定
  • 類型名稱SymTab不如SymbolTable或任何其他縮寫的簡稱
  • 可變靜態變量差不多總是一個壞主意。

編輯:請注意,現在我們知道它來自Java,這解釋了您看到的問題。在Java中,通過變量或其他表達式來引用靜態成員是合法的(但是一個壞主意)。它使得代碼非常混亂。例如:

Thread backgroundThread = new Thread(someRunnable); 
backgroundThread.start(); 
backgroundThread.sleep(1000); 

這使得它看起來你告訴新的線程睡眠,但實際上對靜態Thread.sleep方法,使當前線程休眠的呼叫。一些Java IDE將可選地將其標記爲警告或錯誤。

幸運的是,C#不允許這首先。

+0

感謝您的解釋。我明白你對命名約定的看法。這段代碼實際上來自一本關於口譯員和編譯器的書。這些都是用Java編寫的,但我試圖將它轉換爲C#以應對額外的挑戰,並在此過程中學習C#。 –

+0

請原諒我,如果這是一個愚蠢的問題,但由於在第二個版本中的getter仍然是公共的,爲什麼不'myInstance.symTab'工作? –

+1

@deuteros:因爲你不能像C#中的實例成員(例如通過變量)那樣訪問* static *成員。你可以在Java中,但這是Java中的一個缺陷,可能會導致代碼不清晰。 (我已經編輯了我的文章,以提供更多細節。) –

0

與你有一個在後面保護的靜態變量,其中與第二液公共場合的第一個解決方案你已經得到了一個受保護的setter。

1

有兩點不同:

  • 在第一種情況下

    ,該symTab財產(考慮將其命名爲SYMTAB相反,按照慣例)是實例屬性。第二,它是靜態的。所以MyClass.symTab將在第二種情況下工作,而不是在第一種,而myInstance.symTab將在另一種情況下工作。

  • 在第一種情況下,屬性的getter和setter都是公共的,而第二種情況下,只有getter和setter受保護。