I have a Stream
where I'd like to read data from (as value type segments) and move the position according to the size of the given type (declared as generics).
My current approach:
public byte ReadUInt8(Stream stream) {
return (byte)stream.ReadByte();
}
public ushort ReadUInt16(Stream stream) {
return (ushort)((ReadUInt8() << 8) | ReadUInt8());
}
...
What I'd like to achieve:
public TValue Read<TValue>(Stream stream)
where TValue : struct
{
var bufferSize = Marshal.SizeOf(typeof(TValue));
var buffer = new byte[bufferSize];
if(stream.Read(buffer, 0, bufferSize) == 0)
throw new EndOfStreamException();
return (TValue)buffer; // here's where I'm stuck
// EDIT1: A possible way would be
// return (TValue)(object)buffer;
// but that feels like kicking puppies :/
}
Is this somehow possible? Are there any drawbacks from using Marshal.SizeOf()
(performance-wise etc.)?
Yes, you have just shifted the problem. From not having a
Stream.Read<T>()
to not having aConvert<T>(byte[])
in the std library.And you would have to call it like
Read<int>()
anyway so there isn't a direct advantage overBinaryReader.ReadInt32()
Now when you want to use it from another generic class/method, the
Read<T>()
syntax is useful but for the implementation you might as well map it to BinaryReader calls. I'm afraid that will require boxing: