原始数据类型的通用BitConverter.GetBytes?

时间:2011-07-24 23:06:58

标签: vb.net

所以我知道有this question解决了获取对象字节的需要。但我想知道是否有一种在泛型类型上调用BitConverter.GetBytes的方法,我知道该类型是基元(Int32,UInt16等)。

因为人们喜欢愚蠢的例子作为实际回答问题的先决条件:

Public Sub Foobar(Of T as Structure)()
    Dim x as T 'Assume T is declared as Int32
    Dim y() as Byte

    y = System.BitConverter.GetBytes(x)
End Sub

上面会抛出你常见的错误:

Overload resolution failed because no accessible 'GetBytes' can be called with these arguments:
    'Public Shared Function GetBytes(value As Double) As Byte()': Value of type 'T' cannot be converted to 'Double'.
    'Public Shared Function GetBytes(value As Single) As Byte()': Value of type 'T' cannot be converted to 'Single'.
    'Public Shared Function GetBytes(value As ULong) As Byte()': Value of type 'T' cannot be converted to 'ULong'.
    'Public Shared Function GetBytes(value As UInteger) As Byte()': Value of type 'T' cannot be converted to 'UInteger'.
    'Public Shared Function GetBytes(value As UShort) As Byte()': Value of type 'T' cannot be converted to 'UShort'.
    'Public Shared Function GetBytes(value As Long) As Byte()': Value of type 'T' cannot be converted to 'Long'.
    'Public Shared Function GetBytes(value As Integer) As Byte()': Value of type 'T' cannot be converted to 'Integer'.
    'Public Shared Function GetBytes(value As Short) As Byte()': Value of type 'T' cannot be converted to 'Short'.
    'Public Shared Function GetBytes(value As Char) As Byte()': Value of type 'T' cannot be converted to 'Char'.
    'Public Shared Function GetBytes(value As Boolean) As Byte()': Value of type 'T' cannot be converted to 'Boolean'.


我认为可行的一个解决方案是调用GetType()的大型Select Case,但这非常慢(因为拳击)并且看起来很难看。我认为,因为我用T的原始数据类型调用我的更高级别的类,编译器将足够聪明地弄明白,但我认为我没有提供足够的信息来推导出什么是T的底层值是在被调用实例的编译时。

2 个答案:

答案 0 :(得分:1)

我有一个类似的问题并通过首先将通用T类型转换为对象然后调用BitConverter.GetMethod()来解决它,即

    Dim obj As Object = CType(Value, T)
    Dim bytes As Byte() = BitConverter.GetBytes(obj)

答案 1 :(得分:0)

自己解决了。

使用我的问题the solution中提供的精简版"Faster way to convert from a String to generic type T when T is a valuetype?",我能够为名为GenericGetBytes的通用类型创建一个扩展方法,该方法将使用相同的委托技巧来访问GetBytes类中的相应System.BitConverter方法。这将保留相当大的性能,而不必为每种类型编写一堆重载函数。

代码:

<System.Runtime.CompilerServices.Extension()>
Friend Function GenericGetBytes(Of T As Structure)(ByVal value As T) As Byte()
    Return GenericBitConverter(Of T).GetBytes(value)
End Function

Private Class GenericBitConverter(Of T As Structure)
    Private Sub New()
    End Sub

    Friend Delegate Function GetBytesFunc(ByVal value As T) As Byte()
    Friend Shared ReadOnly GetBytes As GetBytesFunc = FetchGetBytesFunc()

    Private Shared Function FetchGetBytesFunc() As GetBytesFunc
        Return DirectCast(GetBytesFunc.CreateDelegate(GetType(GetBytesFunc),
                                GetType(BitConverter).GetMethod("GetBytes", New Type() {GetType(T)})), 
                          GetBytesFunc)
    End Function
End Class


调用:

Public Sub Foobar(Of T As Structure)(ByVal value As T)
    Debug.Print(BitConverter.ToString(value.GenericGetBytes))
End Sub

Call Foobar(Of Int16)(42)


输出:

2A-00



编辑:然后我发现CType运算符无法从基类转换为派生类,这意味着这个问题和答案的整个目标只是变得没有实际意义,因为我必须将所有的CType运算符移回派生类。哈

相关问题