2011-03-03 216 views
8

這裏就是我談論的例子...爲什麼不能通過實例變量訪問共享/靜態成員?

Public Class Sample1 

    Public Shared Function MyValue() As Integer 
     Return 0 
    End Function 

    Public Sub Code() 
     Dim ThisIsBad = Me.MyValue 
     Dim ThisIsGood = Sample1.MyValue 
    End Sub 

End Class 

Me.MyValue給出VB.NET警告,(相當於代碼給出)在C#中的錯誤。這是否有特別的原因?我發現使用'Me.MyValue'訪問共享函數更直觀/自然 - 但我避免它將我的警告保持爲0.

是否有其他人只是決定'呃,這樣做更有意義其他方式「還是有一些我不明白的技術原因?

編輯:

謝謝大家。我在想它是錯誤的,更像是OOP中的「子類」。即使在基類中聲明瞭某些東西,也可以通過您擁有的實例來訪問它。但是這種關係與共享或靜態關係並不相同。

回答

7

靜態成員的定義是在水平,而不是實例級別,所以訪問使用this(或VB me)的靜態成員並沒有真正感受到的權利聲明(而不是正確的在C# )

this.something(或me.something)意味着你正在訪問「東西」這是特定於特定的實例,同時,再次,靜態成員在整個該類的所有實例共享。

+0

這。 MyValue函數不屬於任何一個實例;因此應該在單個實例的範圍之外訪問它。試圖使用me.MyValue的C#等價物會導致編譯器錯誤,所以即使在VB中允許它也是不好的。 – KeithS 2011-03-03 16:03:59

+0

@KeithS - 你是否打算成爲答案或對我的答案發表評論? – 2011-03-03 16:06:04

+2

評論。我打算說完全一樣的事情,所以我只是誇耀你並用我的方式說出來。 :) – KeithS 2011-03-03 16:07:36

2

Me指向當前實例的Sample1,而MyValue不屬於本身類。因此,VB.NET提醒你看起來很好。

順便說一句,Java那樣它以同樣的方式:

Thread.currentThread().sleep(1000); // warning, as sleep is static 
Thread.sleep(1000); // correct 

乾杯 馬蒂亞斯

3

它誤導你的代碼的讀取器。

代碼應該寫入其他程序員閱讀和理解,我不知道項目的每個細節。通過實例訪問靜態變量使其看起來像一個實例成員 - 您必須檢查該聲明才能看到您錯誤。

「其他程序員」在半年後也許就是你。

1

當你有一個實例和同名的靜態成員的情況下,編譯器很可能保護你免於犯錯。

class X { 

    static public void X1() 
    { 
     Console.WriteLine ("Static"); 
    } 

    public void X1 (bool x1 = false) 
    { 
     X1(); // Which one is this calling? 
     Console.WriteLine ("Instance"); 
    } 
} 

void Main() 
{ 
    X.X1(); // Static 
    new X().X1 (false); // Instance 
} 

結果:

  • 靜態
  • 靜態
  • 實例
1

您不能this參考訪問類級別字段,並且您無法通過類訪問對象級別字段引用它非常有意義。

如果你是通過this指針訪問類級別字段,你最終可能會以如下奇怪的代碼

objA.StaticVariable=1; 
objB.StaticVariable=2; 

這可能會誤導別人,我們實際上是在編輯不同的屬性或字段,但如果是通過訪問班級名稱

Class.StaticVariable=1 
Class.StaticVariable=2 

其明確表示我們正在編輯同一件事。

另外在內存靜態字段存儲在完全不同的地方(接近Type對象),比對象字段,所以我覺得它的超級明顯的區別。

真正的問題是 - 爲什麼它不是VB.NET中的錯誤。我猜測答案是VB是繼承了一些舊的非.NET VB功能,這是非常安全的類型和它的這種繼承的奇怪結果。

相關問題