2016-08-01 2 views
0

데이터 패킷을 구성하는 16 진수 문자열을 반환하는 다음 함수가 있지만이 값은 바이트, UShort, Integer, Single 또는 String이 될 수 있습니다.Vb.net 일반 함수는 형식을 변환 할 수 없습니다. T

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 함수는 위에 지정된 각 데이터 형식에 대한 오버로드 된 함수이므로 값에 따라 다른 문자열을 반환합니다. 공공 기능 ToHex (바이트로 16 진수) 문자열과 같은 : 유형의 가치 나, 함수가 일반적인 만들려고하면

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 함수 각각에 대해 '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 
+0

나는 모든 유형에 대한 자신의 과부하를 생각한다 보다 명확하고 유지 보수 가능한 접근 방식이 될 것입니다. – Fabio

+0

ToHex 란 무엇입니까? 그 기능이 내장되어 있습니까? 아니면 쓴 것입니까? 그것을 일반화 할 필요가 있거나 단순히'Object'를 받아 들일 필요가 있습니다. 여기서 제네릭을 사용하는 것이 모두 유용하다는 것을 확신하지 못합니다. – sstan

+0

제네릭을 계속 사용한다면 ToHex 메소드는 전달 된 타입을 결정하기 위해'If' 나'Select' 문을 사용해야하고 – Fabio

답변

0

당신은 당신의 ToHex 기능은 객체을 만들 수 있습니다. 이것은 모든 기본 유형이 하나의 공통 기본 유형 (오브젝트)만을 공유하기 때문에 모든 기본 유형에 대해 단일 기능을 갖는 유일한 방법입니다. 이것은 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
정수 : 00,000,001 012,351,
정수 : 00000001
USHORT : FFFF
USHORT : 0001
USHORT : 0001
문자열 : 당신이 객체를 확장하지 않으려면 537472696E67

, 당신은 <Extension>를 제거하고 그냥 호출 할 수 있습니다 ToHex(Single.MaxValue)

처럼 우리는 그런 종류의 당신은 여기 https://stackoverflow.com/search?q=numeric+generic+C%23

+0

이 코드는 앞에 오는 0이있는 데이터에 대해서는 작동하지 않습니다. 작동하려면 앞에 오는 0이 필요합니다. 예를 들어 값 8이 UShort로 전달되면 반환되는 문자열은 "8"이고, "0008"이 필요하지만 바이트로 전달 된 경우 "08"이 반환되어야합니다. – Logan

+0

논리가 맞습니까? 선행 0의 수는? – djv

+0

바이트 유형의 경우 UShort의 경우 1 바이트가 필요하고 2 바이트 (0000), 정수 및 단일의 경우 4 바이트 (00000000), 문자열의 경우 1 바이트가 필요합니다. – Logan

0

원하는 정확히 무엇을 달성 할 수없는 이유보기 케이스 (또는 내가 이해하는 것) 나는 공통의 물건을 자신의 (사적) 방법으로 넣을 것이고 그것을 공공의 것에서 올바른 "hexed"값으로 부를 것이다.
이렇게하면 핵심 코드를 이동하고 중복 된 코드는 간단합니다. (BCL 팀이 Enumerable에 대해 다른 오버로드를 작성한 방법을 살펴보십시오.exemple에 대한 최대) 나를 위해에있는 아마 엄격한 옵션과 관련된 단일의 ToHex 과부하가 나를 위해 작동하지 않는 보조 노트()으로

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 

관련 문제