Visual Basic动态类型转换和比较

时间:2013-10-08 17:29:44

标签: vb.net type-conversion

我正在尝试创建一个函数来测试DataRow对象的两个成员的相等性,所有这些成员最初都是字符串,但需要在比较之前转换为它们的实际数据类型。如果数据无法转换为实际数据类型,则该函数应返回false。这是我正在拍摄的一般框架。

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

我得到的错误是:Type 'dType' is not defined.

我尝试使用Of子句对该函数进行泛化:

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

但是,尝试此操作会导致错误:Operator '=' is not defined for types 'dtype' and 'dtype'.一般来说,我认为我没有正确使用of子句。

给定一个数据行,dr,有两个字段t1_sizet2_size,各自的值为“01.92”和“1.92”,我的目标是调用函数这样:

Dim match as Boolean = compareValues(dr, "size", Double) 'evaluates to True

如果相同的数据行和字段具有各自的值“01.90”和“1.92”,则应以相同的方式调用该函数,但返回False。

t1_sizet2_size各自的值视为“apple”和“01.92”,应该以与前面示例相同的方式调用该函数,并仍然返回False。

分辨率/执行:

Steven Doggart和Styxxy将他们的每一份贡献带回家。请在下面找到工作代码:

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

如下所示,假设您有一个DataRow,您希望比较相等的两列,“t1_size”和“t2_size”,每个列都包含一个浮点数的字符串表示:

Dim match as Boolean = compareValues(Of Double)(dr, "size")

1 个答案:

答案 0 :(得分:3)

你倒退了。当dtypeType变量时,您应该使用CTypeDynamic方法,例如:

Private Function compareValues(row as DataRow, field as String, dType as Type) as Boolean
    ' ...
    val1 = CTypeDynamic(raw1, dtype)
    ' ...
End Function

dtype是通用类型时,您应该使用CType,例如:

Private Function compareValues(Of dtype)(row As DataRow, field As String) As Boolean
    ' ...
    val1 = CType(raw1, dtype)
    ' ...
End Function

但是,您可能希望将raw1raw2定义为Object并将其设置为实际字段值。我怀疑你是否真的想将它们转换为字符串只是为了转身并再次将它们转换回适当的数据类型。例如:

Dim raw1 As Object = row("t1_" + field)
Dim raw2 As Object = row("t2_" + field)

正如Styxxy指出的那样,在.NET Framework 3.5版中添加了通用Field扩展方法。它为您进行转换,因此您可以跳过“原始”部分并执行以下操作:

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