3

我正在尝试创建一个函数来测试 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_size考虑和的各自值t2_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")
4

1 回答 1

3

你倒过来了。当dtype是一个Type变量,你应该使用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

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

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

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

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
于 2013-10-08T18:13:44.657 回答