I have some difficulty with returning a generic.
I have a class named Scalar. Its purpose is to deal with numeric values only. Obviously that's not truly enforcable without throwing runtime exceptions. The best I am able to do is using the Structure constraint. So far, so acceptable.
In the class I work with a stream which contains bytes representing such generics. These can be sequences of type Byte, Int32, UInt64 etc. They are all of the same data type, and they represent numbers.
Consider a function Item within this class, in which I call a function, which reads from that stream. The result is stored in a byte array. I know the array's bound because of evaluating and storing it at construction time, using Marshal.SizeOf. However, I am struggling at returning this byte array as datatype T.
'SizeOf:
Imports System.Runtime.InteropServices.Marshal
Public Class Scalar(Of T As Structure)
Private gtValue As T
Private giSize As Int32
Public Sub New(Value As T)
gtValue = Value
giSize = SizeOf(gtValue)
End Sub
Public Function Value() As T
Return gtValue
End Function
Public Function Item() As T
'The return value stems from a stream. It is packed into a bytes array
'of appropriate size (8 B for Int64, Double, 1 B for Byte etc.). The
'Byte array is in little endian order.
Dim abItem(0 To giSize - 1) As Byte 'Result of Stream function.
'How do I return abItem as T?
End Function
End Class
Of course, I could run through the array and compose the number itself byte by byte, then returning it as a non-generic datatype, say as an Int64:
Dim iElement As Int64 = 0
For i = 0 To giIndexLenBytes - 1
'Shift prior content 8 bits to the left and add new (unsigned) byte.
iElement <<= 8
iElement += abItem(i)
Next
Return iElement
I could also use BitConverter and a Select block to obtain the number as well, but that would be even clumsier and in the end not a tad more helpful:
Dim iElement As Int64
Select Case gtValue.GetType.ToString
Case "Byte"
iElement = abItem(0)
Case "Integer"
iElement = BitConverter.ToInt32(abItem, 0)
Case "Long"
iElement = BitConverter.ToInt64(abItem, 0)
'etc...
End Select
Obviously, I can obtain the number in several ways.
However, is there a possibility to assign the once obtained number to a returnable T variable, so that the generic class is useful for the user of it?