As we have already seen, every type in VB.NET, whether it is a value type or a reference type, ultimately inherits from the root class System.Object . The class ValueType inherits directly from Object . ValueType is the root for all value types, such as structures and simple types like Integer and Decimal . Public Instance Methods of Object There are four public instance methods of Object , three of which are virtual and frequently overridden by classes. Equals Overridable Overloads Public Function Equals(_ ByVal obj As Object) As Boolean This method compares an object with the object passed as a parameter and returns True if they are equal. Object implements this method to test for reference equality. ValueType overrides the method to test for content equality. Many classes override the method to make equality behave appropriately for the particular class. Tostring Overridable Public Function ToString() As String This method returns a human-readable string representation of the object. The default implementation returns the type name . Derived classes frequently override this method to return a meaningful string representation of the particular object. GetHashCode Overridable Public Function GetHashCode() As Integer This method returns a hash value for an object, suitable for use in hashing algorithms and hashtables. You should normally override this method if you override ToString . GetType Public Function GetType() As Type This method returns type information for the object. This type information can be used to get the associated metadata through reflection , a topic we discuss in Chapter 10. Protected Instance Methods There are two protected instance methods, which can be used only within derived classes. MemberWiseClone Protected Function MemberwiseClone() As Object This method creates a shallow copy of the object. To perform a deep copy, you should implement the ICloneable interface. We will discuss shallow and deep copy later in this chapter. Finalize Overrides Protected Sub Finalize() This method allows an object to free its resources and perform other cleanup operations before the object is reclaimed by garbage collection. The Finalize method is invoked automatically by the garbage collector, but in a nondeterministic manner. Once an object is no longer needed, the Finalize method will be called at a time determined by the garbage collector, but the program itself cannot predict exactly when this will happen. We discuss finalization in Chapter 10. Generic Interfaces and Standard Behavior If you are used to a language like Smalltalk, the set of behaviors specified in Object may seem quite limited. Smalltalk, which introduced the concept of a class hierarchy rooted in a common base class, has a very rich set of methods defined in its Object class. I counted 38 methods! [1] These additional methods support features such as comparing objects and copying objects. The .NET Framework class library has similar methods, and many more. But rather than putting them all in a common root class, .NET defines a number of standard interfaces , which classes can optionally support. This kind of organization, which is also present in Microsoft's Component Object Model (COM) and in Java, is very flexible. We will study interfaces later in this chapter, and we will discuss some of the generic interfaces of the .NET Framework. [1] The methods of Smalltalk's Object class are described in Chapters 6 and 14 of Smalltalk-80: The Language and its Implementation , by Adele Goldberg and David Robson. Using Object Methods in the Customer Class As a simple illustration of Object methods, let's look at our Customer class before and after overriding the Equals , ToString , and GetHashCode methods. Default Methods of Object If our class does not provide any overrides of the virtual instance methods of Object , our class will inherit the standard behavior. This behavior is demonstrated in CustomerObject\Step1 . ' Customer.vb Public Class Customer Public CustomerId As Integer Public FirstName As String Public LastName As String Public EmailAddress As String Public Sub New(_ ByVal id As Integer, _ ByVal first As String, _ ByVal last As String, ByVal email As String) CustomerId = id FirstName = first LastName = last EmailAddress = email End Sub End Class Here is the test program: ' TestCustomer.vb Imports System Module TestCustomer Sub Main() Dim cust1 As Customer Dim cust2 As Customer cust1 = New Customer(_ 99, "John", "Doe", "john@rocky.com") cust2 = New Customer(_ 99, "John", "Doe", "john@rocky.com") ShowCustomerObject("cust1", cust1) ShowCustomerObject("cust2", cust2) CompareCustomerObjects(cust1, cust2) End Sub Private Sub ShowCustomerObject(_ ByVal label As String, ByVal cust As Customer) Console.WriteLine("---- {0} ----", label) Console.WriteLine(_ "ToString() = {0}", cust.ToString()) Console.WriteLine(_ "GetHashCode() = {0}", cust.GetHashCode()) Console.WriteLine(_ "GetType() = {0}", cust.GetType()) End Sub Sub CompareCustomerObjects(_ ByVal cust1 As Customer, _ ByVal cust2 As Customer) Console.WriteLine(_ "Equals() = {0}", cust1.Equals(cust2)) End Sub End Module Run the test program and you will see this output: ---- cust1 ---- ToString() = CustomerObject.Customer GetHashCode() = 4 GetType() = CustomerObject.Customer ---- cust2 ---- ToString() = CustomerObject.Customer GetHashCode() = 6 GetType() = CustomerObject.Customer Equals() = False The default implementation is not at all what we want for our Customer object. ToString returns the name of the class, not information about a particular customer. Equals checks for reference equality, not equality of contents. In our example, we have two different references to Customer objects with the same content, and Equals return False . Overriding Methods of Object The version of the project in CustomerObject\Step2 demonstrates overriding these virtual methods. Our override of Equals tests for content equality. ' Customer.vb Public Class Customer Public CustomerId As Integer Public FirstName As String Public LastName As String Public EmailAddress As String Public Sub New(_ ByVal id As Integer, _ ByVal first As String, _ ByVal last As String, ByVal email As String) CustomerId = id FirstName = first LastName = last EmailAddress = email End Sub Public Overloads Overrides Function Equals (_ ByVal obj As Object) As Boolean Dim cust As Customer = obj Return (cust.CustomerId = CustomerId) End Function Public Overrides Function GetHashCode () As Integer Return CustomerId End Function Public Overrides Function ToString () As String Return FirstName & " " & LastName End Function End Class The test program is identical. Here is the new output: ---- cust1 ---- ToString() = John Doe GetHashCode() = 99 GetType() = CustomerObject.Customer ---- cust2 ---- ToString() = John Doe GetHashCode() = 99 GetType() = CustomerObject.Customer Equals() = True |