C# 如何使用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

我试图以一种通用的方式使用BinaryReader读取方法。只有在运行时,我才知道正在读取的数据类型

   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过时,他们将使用chained
if进行所有手动类型检查。