Maury Markowitz
Maury Markowitz

Reputation: 9283

Should I use two methods with String and Integer,or use TypeOf?

We have a series of collections of objects that all have two fields for sure, an integer "key" and a string "name". We have methods that return a particular instance based on the name or key...

Public ReadOnly Property Inflations(ByVal K as String) As InflationRow
    ' look for K in the names
End Property
Public ReadOnly Property Inflations(ByVal K as Integer) As InflationRow
    ' look for K in the keys
End Property

COM interop has the interesting side effect that only the first method with a given name is exported. So we added this...

Public ReadOnly Property Inflations(ByVal K as Object) As InflationRow
    Return Inflations(K)
End Property

This leads to some confusion when reading the code, and multiple lines doing the same thing. So what if I replace all of this with...

Public ReadOnly Property Inflations(ByVal K as Object) As InflationRow
    If TypeOf K Is String then
        'do a string lookup on name
    else
        'try it on the key
    end if
End Property

This does the same thing in the end, but seems much easier to read and keeps all the code in the same place. But...

Most of the calls into this code doesn't come from COM, but our own code. Will many calls to TypeOf in our .net code be significantly slower than allowing the runtime to make this decision through polymorphism? I really don't know enough about the runtime to even guess.

Upvotes: 0

Views: 29

Answers (1)

SSS
SSS

Reputation: 5403

Test it and see! :-)

Option Strict On

Module Module1
  Sub Main()
    Dim irc As New InflationRowCollection
    For i As Integer = 0 To 4999
      irc.InflationList.Add(New InflationRow With {.IntProperty = i, .StrProperty = i.ToString})
    Next i
    Dim t1 As Date = Now
    For i As Integer = 0 To 4999
      Dim ir1 As InflationRow = irc.Inflations(i)
      Dim ir2 As InflationRow = irc.Inflations(i.ToString)
    Next i
    Dim t2 As Date = Now
    For i As Integer = 0 To 4999
      Dim ir1 As InflationRow = irc.InflationsObj(i)
      Dim ir2 As InflationRow = irc.InflationsObj(i.ToString)
    Next i
    Dim t3 As Date = Now
    Console.WriteLine("Typed property: " & (t2 - t1).TotalSeconds & " sec" & vbCrLf & "Object property: " & (t3 - t2).TotalSeconds & " sec")
    Console.ReadKey()
  End Sub
End Module

Class InflationRow
  Property IntProperty As Integer
  Property StrProperty As String
End Class

Class InflationRowCollection
  Property InflationList As New List(Of InflationRow)

  ReadOnly Property InflationsObj(o As Object) As InflationRow 'use different name for testing, so we can compare
    Get
      If TypeOf o Is String Then
        Return Inflations(DirectCast(o, String))
      ElseIf TypeOf o Is Integer Then
        Return Inflations(DirectCast(o, Integer))
      Else
        Throw New ArgumentException
      End If
    End Get
  End Property

  ReadOnly Property Inflations(k As String) As InflationRow
    Get
      For Each ir As InflationRow In InflationList
        If ir.StrProperty = k Then Return ir
      Next
      Return Nothing
    End Get
  End Property

  ReadOnly Property Inflations(k As Integer) As InflationRow
    Get
      For Each ir As InflationRow In InflationList
        If ir.IntProperty = k Then Return ir
      Next
      Return Nothing
    End Get
  End Property
End Class

Upvotes: 2

Related Questions