tags:

views:

171

answers:

1

Given in the following language specification, for me at least, calling Db.Foobar() [In the following code] does not indeed call off to the Shared Constructors of the base classes. I am curious as to a) is this my own fault for doing something wrong or b) is this an error in the language specification

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  A: 

VB.NET does call shared constructor of the base class before instantiating the class or its derived classes or upon accesses to Shared members of the class itself.

From a theoretical point of view, Shared (static) stuff are non-object oriented stuff in an object oriented language (e.g. they don't support polymorphism.) There's no need to call the base class Shared constructor when you access static members of a derived class. Each class is a completely separate entity when it comes to static members.

UPDATE (re comment):

It think you are referring to the following code snippet:

By contrast, the following example produces predictable output, because the Shared constructor for the class A must execute before the Shared constructor for the class B, which derives from it:

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

That link says the output should be (which is not):

Init A
Init B
B.G

this is clearly wrong (regardless of being old.) Even if you don't consider the implications of the Shared constructor, the output doesn't have "1" and "2" printed directly by Main.

Beside that, I think that page contradicts itself. The rules mentioned near the beginning of the page are correct (except the item "Shared constructors are run before any types that derive from the type are loaded." in which "loaded" is a bit vague. Instantiated is a more correct word here.) None of the rules say if derived class Shared constructor is called, base class Shared constructor is guaranteed to be called too.

Mehrdad Afshari