c# - 在运行时(可能使用反射)调用泛型方法时,我可以指定“T”吗?
问题描述
我有许多 JSON 文件,每个文件都包含一个不同类对象的列表。
我可以从文件名中计算出我期望的数据,并有一个通用的 JSON 文件阅读器,它返回正确的数据,但我不知道如何将它分配给调用方法中允许我访问结果的任何内容作为实际类型。
我目前正在使用这条线:
var k = ReadJson<dynamic>(filePath, typeof(List<>).MakeGenericType(new[] { type }));
或者
var k = ReadJson<Object>(filePath, typeof(List<>).MakeGenericType(new[] { type }));
但他们都给了我
无法将“System.Collections.Generic.List`1[Abc.Shared.Models.Location]”类型的对象转换为“System.Collections.Generic.List`1[System.Object]”类型。
猜想:既然我不能直接调用ReadJson,我可以通过反射来调用ReadJson,指定泛型'T'的类型吗?如果可能的话,我无法解决。
(为了完整起见,这里是通用方法 - 我认为问题不在这里)
public static List<T> ReadJson<T>(string filePath, Type t) where T : class, new()
{
List<T> regions = new List<T>();
using (StreamReader file = System.IO.File.OpenText(filePath))
{
JsonSerializer serializer = new JsonSerializer();
regions = (List<T>)serializer.Deserialize(file, t);
}
return regions;
}
解决方案
您不能强制List<T>
转换为List<TBase>
(并且object
是所有引用类型的基础),因为List<T>
它不是协变的。你可以投到IEnumerable<T>
,IEnumerable<TBase>
因为IEnumerable<T>
是协变的。由于历史原因,甚至数组也是协变的,因此您可以T[]
转换为TBase[]
. 我会给你两个样本:
public static IEnumerable<T> ReadJson1<T>(string filePath, Type t) where T : class, new()
{
IEnumerable<T> regions = new List<T>();
using (StreamReader file = System.IO.File.OpenText(filePath))
{
JsonSerializer serializer = new JsonSerializer();
regions = (IEnumerable<T>)serializer.Deserialize(file, t);
}
return regions;
}
public static T[] ReadJson2<T>(string filePath, Type t) where T : class, new()
{
using (StreamReader file = System.IO.File.OpenText(filePath))
{
JsonSerializer serializer = new JsonSerializer();
var regions = (T[])serializer.Deserialize(file, t);
return regions;
}
}
Type type = typeof(MyObject);
IEnumerable<object> k1 = ReadJson1<object>("test.json", typeof(List<>).MakeGenericType(new[] { type }));
object[] k2 = ReadJson2<object>("test.json", type.MakeArrayType());
推荐阅读
- java - 无法在简单程序上解析符号“上下文”
- apache-kafka - Hbase中的数据类型转换
- ios - iOS 应用内订阅产品的价格是否要求与通过网站直接提供的类似产品的价格相同或更低?
- git - GitHub:抱歉,此差异不可用(已删除分叉)
- reactjs - React Native - 全局事件监听器
- c# - C# 如果整数对于 Int32 来说太大,我如何存储它并用它做数学运算
- javascript - 如果未在配置文件中设置实体目录,TypeORM 无法找到实体
- c - 使用 malloc 对结构进行数据对齐
- android - 按钮 OnclickListener 中的未定义箭头 - Android Studio
- unity3d - 如何在屏幕中心显示 Unity Google AdMob 横幅