2009-06-19 59 views
6

我有3种类似功能的通用方法,即只改变基于数值类型:创建转换字符串可空号

<Extension()> _ 
Public Function ToNullableShort(ByVal str As String) As Short? 
    Dim intReturn As Short 
    If Short.TryParse(str, intReturn) Then 
     Return intReturn 
    Else 
     Return Nothing 
    End If 
End Function 

<Extension()> _ 
Public Function ToNullableByte(ByVal str As String) As Byte? 
    Dim intReturn As Byte 
    If Byte.TryParse(str, intReturn) Then 
     Return intReturn 
    Else 
     Return Nothing 
    End If 
End Function 

<Extension()> _ 
Public Function ToNullableLong(ByVal str As String) As Long? 
    Dim intReturn As Long 
    If Long.TryParse(str, intReturn) Then 
     Return intReturn 
    Else 
     Return Nothing 
    End If 
End Function 

我试图让一个泛型函数出这一点,但不能做到这一点。我怎样才能做一个通用的函数,将采取一个具体的T,并使其为可空(T)?

回答

10

这里有一个相同的问题(在C#):Convert string to nullable type (int, double, etc...)

Public Function ConvertString(Of T As Structure)(ByVal value As String) As System.Nullable(Of T) 
    Try 
     Return DirectCast(Convert.ChangeType(value, GetType(T)), T) 
    Catch 
     Return Nothing 
    End Try 
End Function 
+1

这太糟糕了,没有一个Convert.TryChangeType方法,这将避免在输入字符串无效时不得不吃掉异常。 – jjxtra 2009-06-19 19:39:54

3

如何:

Public Shared Function Parse(Of T As Structure)(ByVal value As String) As T? 
    If String.IsNullOrEmpty(value) Then 
     Return Nothing 
    End If 
    Return New T?(DirectCast(TypeDescriptor.GetConverter(GetType(T)).ConvertFromInvariantString(value), T)) 
End Function 

(注意我用反射镜把这种从下面的C#)

你可以添加围绕ConvertFromInvariantString的try/catch,但说实话,我宁愿让代码抛出一个异常,如果我给它一些stoopid - 留空值为空案件。

这样做的好处是它可以与自己的结构一起工作,只要您将类型转换器与它们关联起来,您可以轻松地(使用属性或在运行时)轻松完成。

public static T? Parse<T>(string value) where T : struct 
{ 
    if (string.IsNullOrEmpty(value)) return null; 
    return (T)TypeDescriptor.GetConverter(typeof(T)) 
     .ConvertFromInvariantString(value); 
}