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

风流意气都作罢 提交于 2019-11-27 20:27:41

If you have virtual members that are going to be invoked during construction (against best advice, but we've already agreed on that), then you need to move your initialization into a separate method, that can protect itself against multiple calls (i.e. if init has already happened, return immediately). That method will then be invoked by the virtual members and your constructor, before they rely on initialization having occurred.

It's a bit messy, and may represent a minor performance penalty, but there's little else you can do in VB.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!