After debugging a particularly tricky issue in VB.NET involving the order in which instance variables are initialized, I discovered that there is a breaking discrepancy betw
Any well-written class must either ensure any virtual members which could possibly be invoked on a partially-constructed instance will behave sensibly. C# takes the philosophy that a class instance whose field initializers have run will be in a sufficiently-sensible state to allow virtual methods to be used. VB.net takes the philosophy that allowing field initializers to make use of a partially-constructed object (and--with a little work--any parameters passed to the constructor) is more useful than a guarantee that field initializers will run before any virtual methods are called.
IMHO, the right approach from a language-design standpoint would have been to provide a convenient means of indicating that specified field initializers should be run "early" or "late", since there are times each can be useful (though I prefer the "late" style, since it allows constructor parameters to be made available to field initializers). For example:
Class ParamPasserBase(Of T) ' Generic class for passing one constructor parameter
Protected ConstructorParam1 As T
Sub New(Param As T)
ConstructorParam1 = Param
End SUb
End Class
Class MyThing
Inherits ParamPasserBase(Of Integer)
Dim MyArray(ConstructorParam1-1) As String
Sub New(ArraySize As Integer)
MyBase.New(ArraySize)
End Sub
...
End Class
In C#, there's no nice way to have field declarations or initializers make use of arguments passed to a constructor. In vb, it can be done reasonably cleanly as illustrated above. Note that in vb, it's also possible to use a by-reference constructor parameter to smuggle out a copy of the object under construction before any field initializers are run; if a class's Dispose routine is properly written to deal with partially-constructed objects, an object which throws in its constructor can be properly cleaned up.