September 12th, 2007
Programmers moving from VB6 into VB.NET and more object oriented programming in general often wonder about how to use the constructor method (New) and the destructor method (Finalize). I’ve seen questions on this topic come up from time to time in VB related discussion forums. Constructors/Destructors of a sort were in VB6, using the names Initialize and Terminate. However, they could not take parameters and were otherwise limited in what they could do so few programmers used them. In VB.NET, the constructors and destructors are much more powerful. In this article, we’ll look at some ways to use them.
New - The Constructor
In OOP a constructor is a function that has the task of initializing the object. In VB.NET, this is defined as a Sub with the name of New. It’s called whenever an object is created using the New statement, like so:
Dim MyProduct As New Product
This isn’t that different from initializing an object in VB6. However, in .NET we can pass data to the constructor so we could have something like this:
Dim MyProduct As New Product(ProductDataRow)
In our first example, the initialization is handled entirely within the object. It might load default variables internally or just do nothing at all. It might look something like this
Public Sub New() _iD = 0 _description = String.Empty 'other variable init goes here End Sub
If you don’t include a constructor routine in your code, the VB.NET compiler creates one like this for you, except that it doesn’t contain any variable initialization code. However, if you have a New routine with a parameter in your class, no default empty New routine will be created. In that case, you’ll need to create an empty one yourself. Having this no argument constructor is important when you want to use inheritance so it’s usually a good idea to code one. If you don’t want it to be called other than by an inheriting object, use the Protected access modifier for it.
In our second example, we’re send in a DataRow to initialize the object so the code would look something like this:
Public Sub New(ByVal productData As DataRow) _iD = CInt(productData.Item("ProductID")) _description = productData.Item("Description").ToString 'other variable init goes here End Sub
Now, what really can throw some VB6′ers at first is that both these functions can be in the same class so that you can have multiple constructors in a class. As long as each version of the New routine has a different set of parameters, you can define as many constructors as you want or need. I’ve generally found 6-8 to be a good maximum number of overloaded New methods. Much more than that could indicate design problems although there can be exceptional cases.
As I noted above, you can also control how and when an object is created by using access modifiers. For example, you could make one New method public, such as passing in a datarow, and another private, such as passing in a private object unique to your program as seen here:
Public Sub New() 'Does Nothing End Sub Public Sub New(ByVal productData As DataRow) 'Intializes object from datarow End Sub Private Sub New(ByVal productData As DataRow, ByVal secretStuff As SecretSauce) 'Intializes object from datarow plus 'SecretSauce' object End Sub
You can also use private constructors to create a Singleton class pattern by preventing a caller from directly instantiating an object. I’ll be discussing this pattern in an upcoming article.
One thing to keep in mind with your New routines is to keep the code as short as possible here. Lengthy initializations may indicate a design problem with your class, such as it being too complex or bloated. Avoid the temptation of doing everything with this routine. Instead, create additional methods for functionality beyond the basic initialization.
Finalize - The Destructor
The destructor is the last method run by a class. This is called Finalize in VB.NET and it’s called whenever the .NET runtime is told directly or otherwise determines that an object is no longer required. Common uses for the Finalize method is to decrement or increment counters or release resources.
The VB.NET compiler creates a default Finalize method that, behind the scenes, will release variables. However, there may be cases where it’s preferable to have your own code in this routine. When you do this, you have to use the Overrides keyword in your declaration, like so:
Protected Overrides Sub Finalize()
Note that you can’t add parameters to this routine and you can’t use a difference access level than Protected.
One thing to bear in with with Finalize is that there is no set time when this method will be called. Garbage collection, the final release of objects in memory, in the .NET Framework is nondeterministic. Therefore, you should use care when releasing unmanaged objects or calling other classes or components from this routine. You might get unexpected results.
Like the New method, you should also limit the amount of code you put in this routine. My take on it is to simply use the default, compiler built, Finalize unless there is a strong need to perform an action when the object is being destroyed.
I hope this introduction to the way VB.NET uses constructors and destructors has been helpful to you, particularly if you’re migrating to VB.NET from VB6. Let me know what you think or if you have any questions by leaving a comment.
Rate This Article: