Geoffrey
Geoffrey

Reputation: 5432

Does it make sense to cast a reference to an object to a reference to an object of the same class?

The book "Beginning ASP .NET 4 in VB 2010" contains the following:

NOTE: TaxableProduct inherits from Product.

You can also cast in the reverse direction—for example, cast a Product reference to a TaxableProduct reference. The trick here is that this only works if the object that’s in memory really is a TaxableProduct. This code is correct:

Dim theProduct As New TaxableProduct(...)
Dim theTaxableProduct As TaxableProduct
theTaxableProduct = CType(theProduct, TaxableProduct)

But this code generates a runtime error when the last line is executed:

Dim theProduct As New Product(...)
Dim theTaxableProduct As TaxableProduct 
theTaxableProduct = CType(theProduct, TaxableProduct)

Does it make sense to convert from TaxableProduct to TaxableProduct?

Upvotes: 0

Views: 80

Answers (2)

John Alexiou
John Alexiou

Reputation: 29244

This is called upcasting and it is the best you can do sometimes. Think of a situation where inside a method you need to check for a particular derived class an take appropriate action. For example:

Public Class Product
Private productName As String
Public Sub New(ByVal name As String)
    productName = name
End Sub
Public ReadOnly Property Name() As String
    Get
        Return productName
    End Get
End Property

End Class

Public Class TaxableProduct
Inherits Product

Public Sub New(ByVal name As String, ByVal value As Decimal)
    MyBase.New(name)
    productValue = value
End Sub

Private productValue As Decimal
Public Property Value() As Decimal
    Get
        Return productValue
    End Get
    Set(ByVal value As Decimal)
        productValue = value
    End Set
End Property
End Class

Public Class TaxDistrict
Dim districtTaxRate As Decimal
Public Sub New(ByVal taxRate As Decimal)
    districtTaxRate = taxRate
End Sub
Public ReadOnly Property TaxRate() As Decimal
    Get
        Return districtTaxRate
    End Get
End Property

Public Function CalculateTax(ByVal theProduct As Product) As Decimal
    If TypeOf theProduct Is TaxableProduct Then
        ' Upcasting is needed to get the value of the product
        Dim taxProduct As TaxableProduct = CType(theProduct, TaxableProduct)
        Return districtTaxRate * taxProduct.Value
    End If
    Return 0
End Function
End Class

Module Module1

Sub Main()

    Dim cart As New List(Of Product)()
    cart.Add(New Product("Tricyle"))
    cart.Add(New TaxableProduct("Bicyle", 100.0))
    cart.Add(New Product("Candy"))
    cart.Add(New TaxableProduct("Lumber", 400.0))

    Dim kalamazoo As New TaxDistrict(0.09)

    For Each prodInCart As Product In cart
        Console.WriteLine("Tax for {0} is {1}", prodInCart.Name, kalamazoo.CalculateTax(prodInCart))
    Next

End Sub

End Module

Producing the result
  Tax for Tricyle is 0
  Tax for Bicyle is 9.00
  Tax for Candy is 0
  Tax for Lumber is 36.00

Without upcasting it would not have been easy to handle all products and their derived classes.

Upvotes: 1

Steve
Steve

Reputation: 216263

Supposing you have this inheritance...

Public Class Product
    Dim name As String
---
End Class

Public Class TaxableProduct
     Inherits Product
    Dim taxPct As Single
---
End Class 

That means TaxableProduct is a Product
But you can't say Product is a TaxableProduct. it is not true

In your second example you create a Product thus can't convert in a TaxableProduct.
If it was possible which value will have taxPct in your theTaxableProduct

Upvotes: 2

Related Questions