我有以下函数来返回一个十六进制值的字符串来组成一个数据包,但是这个值可以是一个字节、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
函数,公共函数ToHex(十六进制为Byte)为字符串:类型'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
发布于 2016-08-03 21:51:26
您可以让您的ToHex函数接受一个对象。这是跨所有原语类型拥有单个函数的唯一方法,因为所有基本类型只共享一个公共基类型: 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())
单机: 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
发布于 2016-08-03 22:10:15
对于这种情况(或我所理解的情况),我会将常见的东西放在它自己的(私有)方法中,并将其称为公共方法中正确的“已”值。
这样您就可以将核心代码分开,并且重复的代码很简单,您无法绕过它(看看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过载对我不起作用(可能与我的选项严格相关)
https://stackoverflow.com/questions/38705225
复制相似问题