首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Vb.net泛型函数不能转换类型T

Vb.net泛型函数不能转换类型T
EN

Stack Overflow用户
提问于 2016-08-01 17:57:01
回答 2查看 716关注 0票数 0

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

代码语言:javascript
运行
复制
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函数是上面指定的每种数据类型的重载函数,因此它将根据值返回不同的字符串。当我试图使这个函数通用时,

代码语言:javascript
运行
复制
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函数,公共函数ToHex(十六进制为Byte)为字符串:类型'T’的值不能转换为‘Byte’等等。是否有一种方法可以使该函数具有通用性,如果是,这是最好的方法吗?还是应该创建5个不同的函数,显式地说明函数参数中的每种数据类型?

ToHex函数:

代码语言:javascript
运行
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-03 21:51:26

您可以让您的ToHex函数接受一个对象。这是跨所有原语类型拥有单个函数的唯一方法,因为所有基本类型只共享一个公共基类型: object。这在DateTime上不起作用,但是您可以为它添加一个案例。注意:您可以将任何东西传递给这个函数,所以在您的项目中使用它并不是一个好主意。但它至少能实现你想要的。

代码语言:javascript
运行
复制
Option Strict Off
代码语言:javascript
运行
复制
<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

对此进行测试:

代码语言:javascript
运行
复制
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())

单机: 7F7FFFFFSingle: 3F800000Integer: 7FFFFFFFInteger: 00000001 0001String: 00000001 Single: FFFFUShort: 0001 Single:0001 Single: 537472696E67

如果不想扩展对象,可以删除<Extension>并像ToHex(Single.MaxValue)一样调用它

明白为什么我们不能完全实现你想要的,https://stackoverflow.com/search?q=numeric+generic+C%23

票数 0
EN

Stack Overflow用户

发布于 2016-08-03 22:10:15

对于这种情况(或我所理解的情况),我会将常见的东西放在它自己的(私有)方法中,并将其称为公共方法中正确的“已”值。

这样您就可以将核心代码分开,并且重复的代码很简单,您无法绕过它(看看BCL团队如何为Enumerable.Max做不同的重载)

代码语言:javascript
运行
复制
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过载对我不起作用(可能与我的选项严格相关)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38705225

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档