【问题标题】:Convert byte array to generic value type?将字节数组转换为通用值类型?
【发布时间】:2015-07-23 23:04:30
【问题描述】:

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

我目前的做法:

public byte ReadUInt8(Stream stream) {
    return (byte)stream.ReadByte();
}

public ushort ReadUInt16(Stream stream) {
    return (ushort)((ReadUInt8() << 8) | ReadUInt8());
}

...

我想要达到的目标:

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 :/
}

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

【问题讨论】:

    标签: c# generics types stream buffer


    【解决方案1】:
    return (TValue)buffer; // here's where I'm stuck
    

    是的,您刚刚转移了问题。从没有Stream.Read&lt;T&gt;() 到在标准库中没有Convert&lt;T&gt;(byte[])
    无论如何,您都必须将其称为Read&lt;int&gt;(),因此与BinaryReader.ReadInt32()相比没有直接优势

    现在,当您想从另一个通用类/方法中使用它时,Read&lt;T&gt;() 语法很有用,但对于实现,您不妨将其映射到 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;
    

    【讨论】:

    • 是的,您刚刚转移了问题。
    • 您将它从库中的无 Read 更改为无 Convert
    • 嗯,有可能做(T) Convert.ChangeType(value, typeof(T)),但我不太确定我可能会遇到什么样的问题。
    • Edit 刚刚用整数试了一下 -> InvalidCastException :/
    • 是的,byte[] 没有实现 IConvertible。我认为您将需要对象和拳击,但也许有人会发布更好的解决方案。
    猜你喜欢
    • 2010-11-26
    • 1970-01-01
    • 2021-08-09
    • 2020-12-13
    • 2022-10-07
    • 2011-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多