我正在解析数据并且我有一个通用的解析器,我已经基于每个字段给出了有关数据的数据类型和格式(如果适用)的说明。
例如:
<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")
答案 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
用法和试用案例:
1 功能齐全,但丑陋。