Reputation: 539
I'm attempting to create a function to test the equality of two members of a DataRow object, all of which are initially strings, but need to be converted to their actual data types before comparison. If the data can't be converted to the actual data type, the function should return false. This is the general framework that I'm shooting for.
Private Function compareValues(ByVal row as DataRow, ByVal field as String, ByVal dType as Type) as Boolean
' Get the raw values from the DataRow
Dim raw1 As String = row("t1_" + field).ToString()
Dim raw2 As String = row("t2_" + field).ToString()
Dim val1, val2 As dtype
' Try to convert the raw strings to the target type
Try
val1 = CType(raw1, dType) '<--Error here
val2 = CType(raw2, dType) '<--Error here
Catch ex As Exception
Return False ' If either conversion fails, return false
End Try
' Compare the values in their actual types and return false is they don't match
If (Not val1 = val2) Then
Return False
End If
Return True
End Function
The error I get is: Type 'dType' is not defined.
I've attempted to genericize the function by using the Of
clause:
Private Function compareValues(Of dtype)(ByVal row As DataRow, ByVal field As String) As Boolean
Dim raw1 As String = row("t1_" + field).ToString()
Dim raw2 As String = row("t2_" + field).ToString()
Dim val1, val2 As dtype
Try
val1 = CTypeDynamic(Of dtype)(raw1)
val2 = CTypeDynamic(Of dtype)(raw2)
Catch ex As Exception
Return False
End Try
If (Not val1 = val2) Then '<--Error here
Return False
End If
Return True
End Function
Trying this, however, results in the error: Operator '=' is not defined for types 'dtype' and 'dtype'.
Generally speaking, I don't think I'm using the of clause correctly.
Given a datarow, dr
, with two fields, t1_size
and t2_size
, having respective values of "01.92" and "1.92", I'm aiming to call the function like this:
Dim match as Boolean = compareValues(dr, "size", Double) 'evaluates to True
Given the same datarow and fields having respective values of "01.90" and "1.92", the function should be called in the same manner, but return False.
Considering respective values of t1_size
and t2_size
as "apple" and "01.92", the function should be called in the same manner as the previous examples and still return False.
Steven Doggart and Styxxy brought it home with each of their contributions. Please find below the working code:
Private Function compareValues(Of dtype)(row As DataRow, field As String) As Boolean
Dim val1 As dtype
Dim val2 As dtype
Try
val1 = CType(row("t1_" + field), dtype)
val2 = CType(row("t2_" + field), dtype)
Catch ex As Exception
Return False
End Try
If (Not val1.Equals(val2)) Then
Return False
End If
Return True
End Function
Called as follows, assuming you have a DataRow with two columns you wish to compare for equality, "t1_size" and "t2_size", each holding the string representation of a floating point number:
Dim match as Boolean = compareValues(Of Double)(dr, "size")
Upvotes: 4
Views: 2773
Reputation: 43743
You have it backwards. When dtype
is a Type
variable, you should use the CTypeDynamic
method, for instance:
Private Function compareValues(row as DataRow, field as String, dType as Type) as Boolean
' ...
val1 = CTypeDynamic(raw1, dtype)
' ...
End Function
And when dtype
is a generic type, you should use CType
, for instance:
Private Function compareValues(Of dtype)(row As DataRow, field As String) As Boolean
' ...
val1 = CType(raw1, dtype)
' ...
End Function
However, you probably want to define raw1
and raw2
as Object
and set them to the actual field value. I doubt that you really want to convert them to strings just to turn around and convert them back into their proper data type again. For instance:
Dim raw1 As Object = row("t1_" + field)
Dim raw2 As Object = row("t2_" + field)
As Styxxy pointed out, the generic Field
extension method was added in version 3.5 of the .NET Framework. It does the conversion for you, so you could skip the "raw" part and do something like this:
Private Function compareValues(Of dtype)(row As DataRow, field As String) As Boolean
Dim val1 As dtype = row.Field(Of dtype)("t1_" + field)
' ...
End Function
Upvotes: 4