2009-12-30 65 views
9

我遇到了VB.NET和C#(.NET2)中靜態/共享成員可見性的情況。在我看來有點怪在VB.NET:靜態/共享在VB.NET和C#中的可見性

public class A 
    { 
     private static A instance; 
     public static A Instance 
     { 
      get { return instance; } 
     } 

     public string Name { get { } } 
    } 

使用A.Instance.Name // 唯一的名字是 「看得見」


VB.NET:

Public Class A 
    Private Shared _instance As A 

    Public Shared ReadOnly Property Instance() As A 
    Get 
     Return _instance 
    End Get 
    End Property 


    Public ReadOnly Property Name() As String 
    Get 
     Return "" 
    End Get 
    End Property 

End Class 

用法

A.Instance.Instance.Instance.Instance... 

//共享成員的行爲就像一個類的公共一個我可以重複無限..

這是微軟疏忽或VB.NET「功能」?

+3

,如果這是真的,那麼我將它添加到我'爲什麼C#而不是VB'的列表;-) – 2009-12-30 13:40:03

+5

@AdamRalph:這將是不成熟和不反映。 – 2009-12-30 13:52:56

回答

19

這不是一個疏忽,但你的VB代碼觸發警告,這顯然意味着:不要使用這種表示法。

在VB中,靜態成員可以可以經由實例訪問,因爲嚴格來說,VB 沒有static:VB具有關鍵字Shared,這意味着構件是所有實例之間共享,如反對static其中一個成員不屬於任何實例。

現在,這是這些關鍵字之間的語義區別。恰恰相反,這兩種不同的語義傾向於具有完全相同的效果。

當然,static在C#今天相同Shared在VB.NET,但他們的遺產是不同的,VB的Shared只是有着不同的歷史,因此在歷史上有不同的含義。用這個的含義,通過一個實例訪問Shared成員是絕對有意義的。

這也是情理之中的與Option Strict Off(弱類型)一起使用時:在這裏,你有時不知道變量的類型,但你仍然可能需要訪問一個Shared成員。現在,你有沒有選擇,只能使用一個實例來訪問它:

Option Strict Off 
' … ' 
Dim o As Object = New A() 
' Somewhere else, we want to access a static member of A but we don’t know A: ' 
Dim instance = o.Instance 
+0

C#似乎更加準確和清晰,VB.NET應該考慮到它與VB系列的「歷史」兼容性。 無論如何,C#不允許在靜態成員的可見性中通過類名稱和類實例進行重複。它也可以防止像Instance.StaticMember.StaticMember這樣的「無限」字段調用......這可能會讓類實例的用戶感到尷尬。 – serhio 2009-12-30 14:48:30

0

C#編譯器不會讓你引用上的對象實例的靜態屬性,僅在類型本身。這是一個C#而不是.NET CLR限制。 VB.NET將允許這一點,但會警告它。

+0

*這是一個C#而不是.NET CLR限制。* 這個限制是一個很好的,恕我直言,因爲不重複靜態成員的可見性 - 通過類名稱和通過類實例。此外,這可以防止「infinitize」字段調用像Instance.StaticMember.StaticMember.StaticMember.StaticMember.StaticMember ... – serhio 2009-12-30 14:39:22

+0

我完全同意。 – 2009-12-30 15:03:24

9

這是一個功能;這不是一個錯誤。 VB按設計工作。不同的語言對於靜態方法是否可以作爲實例的方法來對待做出不同的選擇。 VB允許它。 C++允許它。 C#沒有。

請記住,不同語言的設計標準是不同的,因此做出的決定是不同的。在C#設計團隊中,我們高度重視一種語言定義,它使得看起來可疑的非法模式成爲可能;因爲沒有含義將接收方實例作爲接收方傳遞給靜態方法(除非計算接收方表達式導致副作用),爲什麼允許用戶輸入無意義的代碼?

在VB設計團隊中,他們重視您工作的代碼,這是您第一次鍵入它的工作方式;如果東西看起來有點狡猾,也許會發出警告,但允許它繼續前進。

如果你有興趣在一些在C#中的靜態調用的設計更微妙的問題,這裏有一個有趣的問題:

http://blogs.msdn.com/ericlippert/archive/2009/07/06/color-color.aspx

+0

真的,因爲我認爲我的實例更*靜態*比*共享*我沒有指望在單例*實例*中有一個*實例*,所以...... – serhio 2009-12-30 15:26:13