Can VB.NET be forced to initialize instance variables BEFORE invoking the base type constructor?

后端 未结 2 477
悲&欢浪女
悲&欢浪女 2020-12-05 13:15

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

2条回答
  •  一个人的身影
    2020-12-05 13:54

    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.

提交回复
热议问题