将字节数组转换为通用值类型?

时间:2022-10-16 19:19:55

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).

我有一个Stream,我想从中读取数据(作为值类型段)并根据给定类型的大小移动位置(声明为泛型)。

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.)?

这有点可能吗?使用Marshal.SizeOf()(性能方面等)有什么缺点吗?

1 个解决方案

#1


return (TValue)buffer; // here's where I'm stuck

Yes, you have just shifted the problem. From not having a Stream.Read<T>() to not having a Convert<T>(byte[]) in the std library.
And you would have to call it like Read<int>() anyway so there isn't a direct advantage over BinaryReader.ReadInt32()

是的,你刚刚改变了问题。从没有Stream.Read ()到std库中没有Convert (byte [])。你必须把它称为Read (),所以没有比BinaryReader.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:

现在,当您想要从另一个泛型类/方法中使用它时,Read ()语法很有用,但是对于实现,您也可以将它映射到BinaryReader调用。我担心会需要拳击:

obcject result = null;
if (typeof(TValue) == typeof(int))
  result = reader.ReadInt32();
else if (typeof(TValue) == typeof(double))
  result = reader.ReadDouble();
else ...

return (TValue) result;

#1


return (TValue)buffer; // here's where I'm stuck

Yes, you have just shifted the problem. From not having a Stream.Read<T>() to not having a Convert<T>(byte[]) in the std library.
And you would have to call it like Read<int>() anyway so there isn't a direct advantage over BinaryReader.ReadInt32()

是的,你刚刚改变了问题。从没有Stream.Read ()到std库中没有Convert (byte [])。你必须把它称为Read (),所以没有比BinaryReader.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:

现在,当您想要从另一个泛型类/方法中使用它时,Read ()语法很有用,但是对于实现,您也可以将它映射到BinaryReader调用。我担心会需要拳击:

obcject result = null;
if (typeof(TValue) == typeof(int))
  result = reader.ReadInt32();
else if (typeof(TValue) == typeof(double))
  result = reader.ReadDouble();
else ...

return (TValue) result;