Object Instantiation and New Constructors

61 Consider the class definition in Ex am ple 2- 4 . Example 2-4. A class definition Public Class Employee Public EmployeeNumber As Integer Public FamilyName As String Public GivenName As String Public DateOfBirth As Date Public Salary As Decimal Public Function Format As String Return GivenName FamilyName End Function End Class The code in Ex am ple 2- 4 defines a class called Employee. It has five public fields also known as data members for storing state, as well as one member function. The class could be used as shown in Ex am ple 2- 5 . Example 2-5. Using a class Dim emp As New Employee emp.EmployeeNumber = 10 emp.FamilyName = Rodriguez emp.GivenName = Celia emp.DateOfBirth = 1281965 emp.Salary = 115000 Console.WriteLineEmployee Name: emp.Format Console.WriteLineEmployee Number: emp.EmployeeNumber Console.WriteLineDate of Birth: emp.DateOfBirth.ToStringD, Nothing Console.WriteLineSalary: emp.Salary.ToStringC, Nothing The resulting output is: Employee Name: Celia Rodriguez Employee Number: 10 Date of Birth: Thursday, January 28, 1965 Salary: 115,000.00

2.14.1 Object Instantiation and New

Object instantiation is done using the New keyword. The New keyword is, in effect, a unary operator that takes a type identifier as its operand. The result of the operation is a reference to a newly created object of the given type. Consider the following: Imports System.Collections ... Dim ht As Hashtable ht = New Hashtable The Dim statement declares a variable that is capable of holding a reference to an object of type Hashtable, but it doesnt actually create the object. The code in the line following the Dim statement instantiates an object of type Hashtable and assigns to the variable a reference to the newly created 62 object. As with any other variable declaration, the assignment can be done on the same line as the declaration, as shown here: Imports System.Collections ... Dim ht As Hashtable = New Hashtable Visual Basic .NET permits a typing shortcut that produces the same result: Imports System.Collections ... Dim ht As New Hashtable

2.14.2 Constructors

When a class is instantiated, some initialization often must be performed before the type can be used. To provide such initialization, a class may define a constructor. A constructor is a special kind of method. It is automatically run whenever an object of the class is instantiated. Constructor declarations use the same syntax as regular method declarations, except that in place of a method name, the constructor declaration uses the keyword New . For example: Public Class SomeClass Public Sub New Do any necessary initialization of the object here. End Sub End Class To invoke the constructor, a new object must be instantiated: Dim obj As New SomeClass Note the parentheses following the name of the class. Until you get used to it, this method-style syntax following a class name may appear odd. However, the empty parentheses indicate that the classs constructor takes no arguments. Constructors can take arguments, if they are necessary for the initialization of the object: Public Class SomeClass Dim m_value As Integer Public Sub NewByVal InitialValue As Integer m_value = InitialValue End Sub End Class When objects of this class are instantiated, a value must be provided for the constructors argument: Dim obj As New SomeClass27 Constructors can be overloaded, if desired. For example: Public Class SomeClass Dim m_value As Integer 63 Public Sub New m_value = Date.Today.Day for example End Sub Public Sub NewByVal InitialValue As Integer m_value = InitialValue End Sub End Class The constructor that is called depends on the arguments that are provided when the class is instantiated, as shown here: Dim obj1 As New SomeClass calls parameterless constructor Dim obj2 As New SomeClass100 calls parameterized constructor Constructors are usually marked Public . However, there are times when it may be desirable to mark a constructor as Protected or Private . Protected access prohibits the class from being instantiated by any class other than a class derived from this class. Private access prohibits the class from being instantiated by any code other than its own. For example, a particular class design might require that the class itself be in control of whether and when instances are created. Ex am ple 2- 6 shows a class that implements a crude form of object pooling. Example 2-6. Using a private constructor Imports System.Collections ... Public Class MyPooledClass This shared field keeps track of instances that can be handed out. Private Shared m_pool As New Stack This shared method hands out instances. Public Shared Function GetInstance As MyPooledClass If m_pool.Count 0 Then We have one or more objects in the pool. Remove one from the pool and give it to the caller. Return CTypem_pool.Pop , MyPooledClass Else We dont have any objects in the pool. Create a new one. Return New MyPooledClass End If End Function This method must be called to signify that the client is finished with the object. Public Sub ImDone Put the object in the pool. m_pool.PushMe End Sub Declaring a private constructor means that the only way to instantiate this class is through the GetInstance method. Private Sub New End Sub End Class The class in Ex am ple 2- 6 would be used like this: 64 Dim obj As MyPooledClass = MyPooledClass.GetInstance ... obj.ImDone Sometimes when constructors are overloaded, it makes sense to implement one constructor in terms of another. For example, here is a class that has a constructor that takes a SqlConnection object as a parameter. However, it also has a parameterless constructor that creates a SqlConnection object and passes it to the classs parameterized constructor. Note the use of the MyClass keyword to access members of the type: Imports System.Data.SqlClient ... Public Class SomeClass Public Sub New MyClass.NewNew SqlConnection End Sub Public Sub NewByVal cn As SqlConnection Do something with the connection object. End Sub End Class Similarly, MyBase.New can call a base-class constructor. If this is done, it must be done as the first statement in the derived classs constructor. Note that if no explicit call is made, the compiler creates a call to the base-class constructors parameterless constructor. Even if the base class exposes a parameterized constructor having the same signature i.e., the same number and types of parameters as the derived classs constructor, by default the compiler generates code that calls the base classs parameterless constructor. If a class has shared fields that must be initialized before access, and that initialization cant be performed by initializers in the fields declarations, a shared constructor may be written to initialize the fields, as shown here: Public Class SomeClass Public Shared SomeStaticField As Integer Shared Sub New SomeStaticField = Date.Today.Day End Sub End Class The shared constructor is guaranteed to run sometime before any members of the type are referenced. If any shared fields have initializers in their declarations, the initializers are assigned to the fields before the shared constructor is run. Shared constructors may not be overloaded, nor may they have access modifiers Public , Private , etc.. Neither feature is meaningful in the context of shared constructors.

2.14.3 Fields