2009-08-12 91 views
1

在下面的language specification中給出,至少對我來說,調用Db.Foobar()[在下面的代碼中]確實沒有調用基類的共享構造函數。我很好奇,一)這是我自己的錯,爲做錯事或b)這是在語言規範不調用共享構造函數的共享方法

Public MustInherit Class D1 
    Shared Sub New() 
     Console.WriteLine("D1 Static Constructor Called") 
    End Sub 
End Class 

Public MustInherit Class D2 
    Inherits D1 

End Class 

Public Class Da 
    Inherits D2 

    Public Sub New() 
     Console.WriteLine("Public Da Constructor Called") 
    End Sub 
End Class 

Public Class Db 
    Inherits D2 

    Shared Sub New() 
     Console.WriteLine("Db Static Constructor Called") 
    End Sub 

    Public Sub New() 
     Console.WriteLine("Public Db Constructor Called") 
    End Sub 

    Public Shared Sub FooBar() 
     Console.WriteLine("FooBar Called") 
    End Sub 
End Class 

回答

4

VB.NET不調用基類的構造函數共享一個錯誤之前實例的類或其派生類或訪問類本身的成員Shared

從理論上來看,Sharedstatic)的東西都是非面向對象的東西,在面嚮對象語言(例如不支持多態。)沒有必要調用基類Shared構造,當你訪問派生類的靜態成員。當談到靜態成員時,每個類都是一個完全獨立的實體。

UPDATE(再評論):

它想你指的是下面的代碼片段:

相比之下,下面的例子會產生可預測的輸出,因爲該類的共享構造

Imports System 

Module Test 
    Sub Main() 
     Console.WriteLine("1") 
     B.G() 
     Console.WriteLine("2") 
    End Sub 
End Module 

Class A 
    Shared Sub New() 
     Console.WriteLine("Init A") 
    End Sub 
End Class 

Class B 
    Inherits A 

    Shared Sub New() 
     Console.WriteLine("Init B") 
    End Sub 

    Public Shared Sub G() 
     Console.WriteLine("B.G") 
    End Sub 
End Class 
:用於類B的共用構造,其中提煉出來之前A必須執行

這種聯繫說,輸出應爲(不):

Init A 
Init B 
B.G 

這是顯然錯了(無論是舊的),即使你不考慮Shared構造的影響時,輸出不具有由Main直接打印的「1」和「2」。

除此之外,我認爲該頁面自相矛盾。在頁面開頭附近提到的規則是正確的(除了「共享構造函數在從類型派生的任何類型被加載之前運行」的項目之外,其中「加載」有點模糊,實例化在這裏是更加正確的單詞。 )沒有規則說如果調用派生類Shared構造函數,基類Shared構造函數保證也被調用。

0

我用同樣的問題所困擾,並與一些更深入的研究和一些實驗,我來到了以下結論:

共享構造函數是不可繼承的,只有火在同一類級別進行了共享方法被稱爲。

例如:

Public Class Base 
    Shared Sub New() 
     Console.WriteLine("Base Shared Constructor") 
    End Sub 

    Public Shared Sub BaseMethod() 
     Console.WriteLine("Base Method") 
    End Sub 
End Class 

Public Class Derived 
    Inherits Base 

    Shared Sub New() 
     Console.WriteLine("Derived Shared Constructor") 
    End Sub 

    Public Shared Sub DerivedMethod() 
     Console.WriteLine("Derived Method") 
    End Sub 
End Class 

Module Module1 
    Sub Main() 
     Console.WriteLine("Calling Method From Derived") 
     Derived.DerivedMethod() 
     Console.WriteLine("Calling Method From Base") 
     Derived.BaseMethod() 
     Console.Read() 
    End Sub 
End Module 

理想的情況下會產生以下輸出:

Calling Method From Derived 
Base Shared Constructor 
Derived Shared Constructor 
Derived Method 
Calling Method From Base 
Base Method 

但是,實際上產生以下的輸出:

Calling Method From Derived 
Derived Shared Constructor 
Derived Method 
Calling Method From Base 
Base Shared Constructor 
Base Method 

它不是那麼明顯了..我陷入了同一陷阱。我希望它能幫助那些偶然遇到同樣問題的人。