比特转换器可以将字节转换为模板类型“”吗;T”;

本文关键字:类型 转换器 转换 字节 | 更新日期: 2023-09-27 18:28:10

我正试图创建一个模板方法,通过二进制读取器从文件中读取浮点值或双精度值。

我不能使用Binaryreader.readSingle或Binaryreader.readDouble方法,因为它们太具体了。。。可以读取字节,并使用bitConverter将其转换为浮点或双精度。但是bitConverter可以将字节转换为模板类型"T"吗?

// Note: T type will be either float or double 
static void readValues<T>(string fileName, T[] arr, int arrLen)
{
   BinaryReader reader = new BinaryReader(File.Open(fileName, FileMode.Open));
   for(int i = 0; i < arrLen; i++)
   {
      // Have to use one of the methods to read the values
      // which one to use
      // 1. To read float
      //arr[i] = reader.readSingle();
      // 2. To read Double
      //arr[i] = reader.readDouble();

   }
}

比特转换器可以将字节转换为模板类型“”吗;T”;

一如既往,有些人(我)仍然专注于某些乐器。。。如果你只有一把锤子,你所有的问题都会像钉子一样。。。不使用表达式树(如果有人感兴趣,则具有表达式树的另一个版本在帖子的历史记录中)。一个类缓存基于泛型类型T的"right"方法的委托。另一个类使所有内容都作为扩展方法工作。

public static class BinaryReaderEx
{
    public static T Read<T>(this BinaryReader br)
    {
        return BinaryReader<T>.Read(br);
    }
}
public static class BinaryReader<T>
{
    public static readonly Func<BinaryReader, T> Read;
    static BinaryReader()
    {
        Type type = typeof(T);
        if (type == typeof(bool))
        {
            Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, bool>)(p => p.ReadBoolean()));
        }
        else if (type == typeof(char))
        {
            Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, char>)(p => p.ReadChar()));
        }
        else if (type == typeof(string))
        {
            Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, string>)(p => p.ReadString()));
        }
        else if (type == typeof(sbyte))
        {
            Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, sbyte>)(p => p.ReadSByte()));
        }
        else if (type == typeof(short))
        {
            Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, short>)(p => p.ReadInt16()));
        }
        else if (type == typeof(int))
        {
            Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, int>)(p => p.ReadInt32()));
        }
        else if (type == typeof(long))
        {
            Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, long>)(p => p.ReadInt64()));
        }
        else if (type == typeof(byte))
        {
            Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, byte>)(p => p.ReadByte()));
        }
        else if (type == typeof(ushort))
        {
            Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, ushort>)(p => p.ReadUInt16()));
        }
        else if (type == typeof(uint))
        {
            Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, uint>)(p => p.ReadUInt32()));
        }
        else if (type == typeof(ulong))
        {
            Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, ulong>)(p => p.ReadUInt64()));
        }
        else if (type == typeof(float))
        {
            Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, float>)(p => p.ReadSingle()));
        }
        else if (type == typeof(double))
        {
            Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, double>)(p => p.ReadDouble()));
        }
        else if (type == typeof(decimal))
        {
            Read = (Func<BinaryReader, T>)(Delegate)((Func<BinaryReader, decimal>)(p => p.ReadDecimal()));
        }
        else
        {
            throw new ArgumentException();
        }
    }
}

用途:

using (var br = new BinaryReader(ms))
{
    //byte b = BinaryReader<bool>.Read(br);
    //double d = BinaryReader<double>.Read(br);
    //string s = BinaryReader<string>.Read(br);
    // Or
    byte b = br.Read<bool>();
    double d = br.Read<double>();
    string s = br.Read<string>();
}

在这种情况下,泛型不是一个好的设计选择。

您最好编写两个函数,一个接受double数组,另一个接受float数组。编译器会根据您传入的数组选择正确的重载,在您传入所有错误处理(如果我传入一个int数组怎么办?)和类型转换后,它甚至可能比泛型版本的代码更少。