Tuesday, August 10, 2010

A Generic Type Test (in Visual Basic)

I was working on a validation routine recently that involved checking to make sure the string data I was pulling out of an input file was the expected data type.  The input file contained a series of comma delimited lines of text and each line was comprised of a combination of strings, numbers, dates, and boolean values.  Each line had about 30 elements, and I needed to validate every one of them.  In VB, you would do this by using a try catch block and trying to cast the given string value to the expected type.  If the cast worked, your data is valid.  If you get an invalid cast exception (or just a straight up null ref), your cast is invalid.  Sounds easy enough, but I really didn’t want to have to copy the same try/catch block thirty times in a for loop.  So, I wrote the following method:

   1: Private Function CheckType(Of T)(ByVal input As Object) As Boolean
   2:         Dim isType As Boolean = False
   3:  
   4:         Try
   5:             Dim tmp As Object = CType(input, T)
   6:             isType = True
   7:         Catch ex As Exception
   8:             isType = False
   9:         End Try
  10:  
  11:         Return isType
  12:     End Function

The idea here is that you can pass in the string you want to check (input) and the type you want to check it against (T).  I had a terrible time trying to get the type parameter to pass in properly, but thanks to a little help from Justin Spradlin, we got it sorted out.  Now, I can make a quick call to this method right in the middle of an assert function, saving a tremendous amount of code and effort.  Here’s a sample showing how to call the method.  I’ve ripped out most of the assert method call to simplify the code:



   1: If Not dom.Assert((CheckType(Of String)(currentLineArray(0))), ...) Then hasErrors = True
   2: If Not dom.Assert((CheckType(Of String)(currentLineArray(1))), ...) Then hasErrors = True
   3: If Not dom.Assert((CheckType(Of DateTime)(currentLineArray(2))), ...) Then hasErrors = True
   4: If Not dom.Assert((CheckType(Of Boolean)(currentLineArray(3))), ...) Then hasErrors = True
   5: If Not dom.Assert((CheckType(Of Integer)(currentLineArray(4))), ...) Then hasErrors = True

With a little effort, this function can be modified for C#.  It could be as simple as casting the input object as type T in the try/catch block, or even using the ‘Is’ operator.  I’m not sure if the method signature is the same in C# either, as I’ve never tried to pass a Type as a parameter in C#, but I don’t imagine it would take much effort to figure it out.

No comments:

Post a Comment