我正在尝试创建一个模板方法,通过二进制读取器从文件中读取float或double值。
我不能使用Binaryreader.readSingle或Binaryreader.readDouble方法,因为它们太具体了......可能是读取字节并使用bitConverter转换为float或double。但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();
}
}
答案 0 :(得分:2)
像往常一些人(我)仍然关注某些乐器......如果你所拥有的只是一把锤子,你所有的问题都会像钉子一样......没有使用表达树(如果有人有兴趣,那么另一个版本)表达树是历史的一部分)。一个类根据泛型类型T将委托缓存到“右”方法。另一个类使一切都作为扩展方法工作。
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>();
}
答案 1 :(得分:1)
这不是一个好的情况,仿制药将是一个很好的设计选择。
编写两个函数会更好,一个函数接受一个双精度数组,另一个函数接受一个浮点数组。编译器将根据您传入的数组选择正确的重载,并且在您抛出所有错误处理(如果我传入一组int中的内容?)和cast而不是泛型版本后,它甚至可能最终会减少代码。