Vb.net通用函数无法转换类型T.

时间:2016-08-01 17:57:01

标签: vb.net generics

我有以下函数返回一个十六进制值字符串来组成一个数据包,但该值可以是一个字节,UShort,Integer,Single或String。

Public Function GetWriteString(ByVal op As Operation, ByVal value As UShort) As String
    Dim dataString As String = DATA_CONST & WRITE_CONST & op.ToString(Operation.Accessibility.WRITE) & ToHex(value)
    Dim byteCount As String = ToHex(GetByteCount(dataString))
    Return headerString & byteCount & CRC_Module.HeaderCRC(headerString & byteCount) & dataString & CRC_Module.DataCRC(dataString)
End Function

我想让函数成为泛型函数,因为它总是相同的,唯一的区别是ToHex(value)部分。 ToHex函数是上面指定的每种数据类型的重载函数,因此它将根据值返回不同的字符串。当我尝试使函数通用时,

Public Function GetWriteString(Of T)(ByVal op As Operation, ByVal value As T) As String
    Dim dataString As String = DATA_CONST & WRITE_CONST & op.ToString(Operation.Accessibility.WRITE) & ToHex(value)
    Dim byteCount As String = ToHex(GetByteCount(dataString))
    Return headerString & byteCount & CRC_Module.HeaderCRC(headerString & byteCount) & dataString & CRC_Module.DataCRC(dataString)
End Function

它说“重载解析失败,因为无法使用这些参数调用可访问的'ToHex': 公共函数ToHex(十六进制为字节)为String:对于每个重载的ToHex函数,类型'T'的值不能转换为'Byte'“等等。有没有办法使这个函数通用,如果是这样,这是最好的方法,还是应该创建5个不同的函数,明确说明函数参数中的每个数据类型?

ToHex功能:

Public Function ToHex(ByVal characters As String) As String
    ' Variables
    ' byteArray - An array of bytes used to hold the characters which were converted to bytes
    Dim byteArray As Byte() = defaultEncoding.GetBytes(characters)
    ' Converts the byte array to a string of hex values
    Return BitConverter.ToString(byteArray).Replace("-", "")
End Function

Public Function ToHex(ByVal hex As Byte) As String
    Return hex.ToString("X2")
End Function

Public Function ToHex(ByVal word As UShort) As String
    Return word.ToString("X4")
End Function

Public Function ToHex(ByVal int As Integer) As String
    Return int.ToString("X8")
End Function

''' <summary>
''' Converts a float to a string of hex bytes
''' </summary>
''' <param name="float">A float value to be converted</param>
''' <returns>A string of hex bytes</returns>
Public Function ToHex(ByVal float As Single) As String
    ' Variables
    ' byteArray - An array of bytes used to hold the bytes that make up the floating point
    Dim byteArray = defaultEncoding.GetBytes(float)
    ' Reverses the byte array
    Array.Reverse(byteArray)
    ' Converts the byte array to a string of hex values
    Return BitConverter.ToString(byteArray).Replace("-", "")
End Function

2 个答案:

答案 0 :(得分:0)

你可以让你的ToHex函数获取一个Object。这是在所有基本类型中使用单个函数的唯一方法,因为所有基元类型只共享一个公共基类型:object。这不适用于DateTime,但您可以为它添加一个案例。注意:您可以将任何传递给此函数,因此在项目中使用它并不是一个好主意。但它应该至少完成你想要的东西。

Option Strict Off
<Runtime.CompilerServices.Extension>
Public Function ToHex(input As Object) As String
    Dim defaultEncoding = System.Text.Encoding.Default
    Dim result As String
    Dim byteArray As Byte()
    If TypeOf (input) Is String Then
        byteArray = defaultEncoding.GetBytes(input)
        result = BitConverter.ToString(byteArray).Replace("-", "")
    Else
        Dim byteCount = System.Runtime.InteropServices.Marshal.SizeOf(input)
        If (TypeOf (input) Is Single) OrElse (TypeOf (input) Is Double) OrElse (TypeOf (input) Is Decimal) Then
            byteArray = BitConverter.GetBytes(input)
            Array.Reverse(byteArray)
            result = BitConverter.ToString(byteArray).Replace("-", "").PadLeft(byteCount * 2, "0")
        Else
            result = CLng(input).ToString("X").PadLeft(byteCount * 2, "0")
        End If
    End If
    Return result
End Function

测试:

Console.WriteLine("Single: " & Single.MaxValue.ToHex())
Console.WriteLine("Single: " & 1.0F.ToHex())

Console.WriteLine("Integer: " & Integer.MaxValue.ToHex())
Console.WriteLine("Integer: " & 1I.ToHex())
Console.WriteLine("Integer: " & 1I.ToString("X8"))

Console.WriteLine("UShort: " & UShort.MaxValue.ToHex())
Console.WriteLine("UShort: " & 1US.ToHex())
Console.WriteLine("UShort: " & 1US.ToString("X4"))

Console.WriteLine("String: " & "String".ToHex())
  

单身:7F7FFFFF   
单身:3F800000   
整数:7FFFFFFF   
整数:00000001   
整数:00000001   
UShort:FFFF   
UShort:0001   
UShort:0001   
字符串:537472696E67

如果您不想扩展对象,可以删除<Extension>,然后将其称为ToHex(Single.MaxValue)

了解为什么我们无法在此完成您想要的内容https://stackoverflow.com/search?q=numeric+generic+C%23

答案 1 :(得分:0)

对于那种情况(或者我对它的理解),我会把常见的东西放在它自己的(私有)方法中,只需用正确的&#34; hexed&#34;公共价值。
这样你就可以将核心代码分开,重复的代码很简单,你可以绕过它(看看BCL团队如何为Enumerable.Max做出不同的重载)

Public Function GetWriteString(op As Operation, value As UShort) As String
    Return GetWriteStringInternal(op, ToHex(value))
End Function

Public Function GetWriteString(op As Operation, value As Byte) As String
    Return GetWriteStringInternal(op, ToHex(value))
End Function

Public Function GetWriteString(op As Operation, value As Integer) As String
    Return GetWriteStringInternal(op, ToHex(value))
End Function

Public Function GetWriteString(op As Operation, value As Single) As String
    Return GetWriteStringInternal(op, ToHex(value))
End Function

Public Function GetWriteString(op As Operation, value As String) As String
    Return GetWriteStringInternal(op, ToHex(value))
End Function

Private Function GetWriteStringInternal(op As Operation, hexValue As String) As String
    Dim dataString As String = DATA_CONST & WRITE_CONST & op.ToString(Operation.Accessibility.WRITE) & hexValue
    Dim byteCount As String = ToHex(GetByteCount(dataString)) ' Call the Integer overload if I've understood
    Return headerString & byteCount & CRC_Module.HeaderCRC(headerString & byteCount) & dataString & CRC_Module.DataCRC(dataString)
End Function

作为旁注,单身的ToHex超载对我不起作用(可能与Option Strict对我有关)