【问题标题】:Visual Basic Dynamic Type Conversion and ComparisonVisual Basic 动态类型转换和比较
【发布时间】:2013-10-15 18:32:04
【问题描述】:

我正在尝试创建一个函数来测试 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")

【问题讨论】:

  • 我建议在数据行上使用Field method
  • 您的方法存在各种问题。无论如何,只要您愿意传递给定的数据行(其类型已知),您就不需要做所有这些。我从您的示例中了解到,您想要的是一个函数,该函数确定给定数据行的两条记录是否相等,独立于类型(如果类型不同,则该函数将返回 False)。如果这是您想要的,您不必分析数据行类型而是分析其值。您可以按照 Styxxy 的建议使用 Field(可以考虑不同的类型),或者只是通过 TypeOf 检查类型。
  • 感谢@Styxxy 和@steven 的回答!我已经尝试了 Steven Doggart 提供的精简版本,虽然我理解了目标,但我仍然遇到与以前相同的错误:运算符 '=' not defined for types 'dtype' 和 'dtype'。只是为了(可能是不必要的)澄清,我没有创建一个名为 dtype 的类型,这只是我传递给函数的变量名。
  • 使用 Equals 方法。那应该可以。

标签: vb.net type-conversion


【解决方案1】:

你有它倒退。当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 所指出的,通用的 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-01
    • 2018-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    相关资源
    最近更新 更多