C# 如何使用BinaryReader读取方法读取动态数据?
我试图以一种通用的方式使用BinaryReader读取方法。只有在运行时,我才知道正在读取的数据类型C# 如何使用BinaryReader读取方法读取动态数据?,c#,generics,dynamic,binaryreader,C#,Generics,Dynamic,Binaryreader,我试图以一种通用的方式使用BinaryReader读取方法。只有在运行时,我才知道正在读取的数据类型 public static T ReadData<T>(string fileName) { var value = default(T); using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Rea
public static T ReadData<T>(string fileName)
{
var value = default(T);
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var reader = new BinaryReader(fs))
{
if (typeof (T).GetGenericTypeDefinition() == typeof (Int32))
{
value = (dynamic) reader.ReadInt32();
}
if (typeof (T).GetGenericTypeDefinition() == typeof (string))
{
value = (dynamic) reader.ReadString();
}
// More if statements here for other type of data
}
}
return value ;
}
publicstatict读取数据(字符串文件名)
{
var值=默认值(T);
使用(var fs=new FileStream(文件名,FileMode.Open,FileAccess.Read,FileShare.Read))
{
使用(变量读取器=新二进制读取器(fs))
{
if(typeof(T).GetGenericTypeDefinition()==typeof(Int32))
{
value=(动态)reader.ReadInt32();
}
if(typeof(T).GetGenericTypeDefinition()==typeof(string))
{
value=(动态)reader.ReadString();
}
//更多关于其他类型数据的if语句
}
}
返回值;
}
如何避免使用多个if语句?除了使用反射(这会很慢)之外,我能想到的唯一一个您可能更喜欢的选项是构建一个字典:
static object s_lock = new object();
static IDictionary<Type, Func<BinaryReader, dynamic>> s_readers = null;
static T ReadData<T>(string fileName)
{
lock (s_lock)
{
if (s_readers == null)
{
s_readers = new Dictionary<Type, Func<BinaryReader, dynamic>>();
s_readers.Add(typeof(int), r => r.ReadInt32());
s_readers.Add(typeof(string), r => r.ReadString());
// Add more here
}
}
if (!s_readers.ContainsKey(typeof(T))) throw new ArgumentException("Invalid type");
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var reader = new BinaryReader(fs))
{
return s_readers[typeof(T)](reader);
}
}
static object s_lock=new object();
静态IDictionary s_readers=null;
静态T读取数据(字符串文件名)
{
锁(s_锁)
{
如果(s_读取器==null)
{
s_readers=新词典();
s_readers.Add(typeof(int),r=>r.ReadInt32());
添加(typeof(string),r=>r.ReadString());
//在这里添加更多
}
}
如果(!s_readers.ContainsKey(typeof(T)))抛出新的ArgumentException(“无效类型”);
使用(var fs=new FileStream(文件名,FileMode.Open,FileAccess.Read,FileShare.Read))
使用(变量读取器=新二进制读取器(fs))
{
返回s_读取器[类型(T)](读取器);
}
}
调用此函数的代码会更干净,但仍然需要将每个读取函数映射到一个类型。调用
GetGenericTypeDefinition
的目的是什么?如果T
是泛型类型,那么它肯定不是从System.Int32
或System.String
构造的,因为这些不是泛型类型定义。另一方面,如果T
是Int32
或String
,GetGenericTypeDefinition
将在对非泛型类型调用时抛出一个InvalidOperationException
。另外,这是一个不使用泛型的好例子-这里,对所有要支持的类型使用重载是一个更好的解决方案,如果s过时,他们将使用chainedif进行所有手动类型检查。