3

DataRow オブジェクトの 2 つのメンバーの等価性をテストする関数を作成しようとしています。最初はすべて文字列ですが、比較する前に実際のデータ型に変換する必要があります。データを実際のデータ型に変換できない場合、関数は 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 句を正しく使用しているとは思いません。

それぞれの値が「01.92」と「1.92」のdr2 つのフィールドを持つt1_sizeデータ行 と が与えられた場合、次のように関数を呼び出すことを目指しています。t2_size

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

それぞれの値が「01.90」と「1.92」の同じデータ行とフィールドが与えられた場合、関数は同じ方法で呼び出す必要がありますが、False を返します。

と のそれぞれの値を「apple」と「01.92」と考えるt1_sizet2_size、関数は前の例と同じ方法で呼び出す必要があり、それでも 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

次のように呼び出されます。等しいかどうかを比較する 2 つの列 "t1_size" と "t2_size" を持つ DataRow があり、それぞれが浮動小数点数の文字列表現を保持していると仮定します。

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

1 に答える 1

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

ただし、おそらくraw1andraw2を定義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
于 2013-10-08T18:13:44.657 に答える