使用Type和Format字符串将String转换为Object

时间:2014-12-16 20:34:43

标签: .net vb.net

我正在解析数据并且我有一个通用的解析器,我已经基于每个字段给出了有关数据的数据类型和格式(如果适用)的说明。

例如:

<Field Name="DateTime" Type="Pattern" Expression="\d{8} \d{2}\:\d{2}\:\d{2}" DataType="System.DateTime" Format="yyyyMMdd HH:mm:ss" />

类型可以是日期,整数,小数,任何值类型。格式可以是任何日期或数字格式。

Convert.ChangeType没有只接受自定义格式字符串的重载。我试图实施IFormatProvider,但我不知道如何做到这一点。

所以我试图找出如何使这种方法以最通用的方式工作。

  Public Function ConvertValue(Value As String, Type As System.Type, Format As String) As Object

  End Function

日期数据的示例为"20141215 10:07:25" {String},因此我只需致电ConvertValue("20141215 10:07:25", GetType(DateTime), "yyyyMMdd HH:mm:ss")

2 个答案:

答案 0 :(得分:1)

  Sub Test()
    Dim dte As Date = CDate(ConvertValue("20141215 10:07:25", GetType(DateTime), "yyyyMMdd HH:mm:ss"))
    MsgBox(dte.ToString)
    Dim i As Integer = CInt(ConvertValue("1234", GetType(Integer), "0000"))
    MsgBox(i.ToString)
  End Sub

  Public Function ConvertValue(Value As String, Type As System.Type, Format As String) As Object
    If Type Is GetType(Date) Then
      Dim dte As Date
      Dim enAU As New Globalization.CultureInfo("en-AU")
      If Not Date.TryParseExact(Value, Format, enAU, Globalization.DateTimeStyles.None, dte) Then
        dte = New Date
      End If
      Return dte
    ElseIf Type Is GetType(Integer) Then
      Dim i As Integer
      If Not Integer.TryParse(Value, i) Then
        i = 0
      End If
      Return i
    Else
      Return Nothing
    End If
  End Function

答案 1 :(得分:1)

只要您想为所有类型提供一个适合所有类型的功能,您将拥有If / Case语句。我有一个通用转换器来帮助那些通常无法序列化的类型,但转换为没有基础的独立函数使它变得难以理解 1

Private Shared Function ConvertToT(Of T)(obj As String, fmt As String) As T

    If GetType(T) Is GetType(DateTime) Then

        Dim dt As DateTime
        DateTime.TryParseExact(obj, fmt, CultureInfo.CurrentCulture,
                               DateTimeStyles.None, dt)
        Return Convert.ChangeType(dt, GetType(T))

    ElseIf GetType(T) Is GetType(Decimal) Then
        Dim dec As Decimal
        If Decimal.TryParse(obj, dec) Then
            Return Convert.ChangeType(dec, GetType(T))
        Else
            Return Convert.ChangeType(Decimal.MinValue, GetType(T))    ' or exception
        End If

    ElseIf GetType(T) Is GetType(Double) Then
        ' etc etc etc

    End If

End Function

由于您需要使用不同的函数进行转换,因此会得到一个长Case / If块。即使使用ConvertFromInvariantString之类的东西,也有返回类型。在这种情况下,一组扩展似乎没那么粗糙,似乎更有用:

Module ParseExtensions

    <Extension>
    Public Function ParseToDate(dt As DateTime, data As String, 
                   format As String) As DateTime
        Dim newDate As DateTime

        DateTime.TryParseExact(data, format, CultureInfo.CurrentCulture,
                               DateTimeStyles.None, newDate)
        Return newDate
    End Function

    <Extension>
    Public Function ParseToDecimal(dec As Decimal, 
                          data As String) As Decimal
        Dim newDec As Decimal

        If Decimal.TryParse(data, newDec) Then
            Return newDec
        Else
            Return Decimal.MinValue    ' or exception
        End If
    End Function

End Module

用法和试用案例:

  

enter image description here

1 功能齐全,但丑陋。