所以我知道有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的底层值是在被调用实例的编译时。
答案 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运算符移回派生类。哈