C# 我可以指定';T';在运行时调用泛型方法时(可能使用反射)?

C# 我可以指定';T';在运行时调用泛型方法时(可能使用反射)?,c#,generics,reflection,C#,Generics,Reflection,我有许多JSON文件,每个文件都包含不同类对象的列表 我可以从文件名中计算出我期望的数据,并有一个通用的JSON文件读取器,它返回正确的数据,但我不知道如何将其分配给调用方法中允许我以实际类型访问结果的任何内容 我目前正在使用这一行: var k = ReadJson<dynamic>(filePath, typeof(List<>).MakeGenericType(new[] { type })); var k=ReadJson(filePath,typeof(Lis

我有许多JSON文件,每个文件都包含不同类对象的列表

我可以从文件名中计算出我期望的数据,并有一个通用的JSON文件读取器,它返回正确的数据,但我不知道如何将其分配给调用方法中允许我以实际类型访问结果的任何内容

我目前正在使用这一行:

var k = ReadJson<dynamic>(filePath, typeof(List<>).MakeGenericType(new[] { type }));
var k=ReadJson(filePath,typeof(List).MakeGenericType(new[]{type}));

var k=ReadJson(filePath,typeof(List).MakeGenericType(new[]{type}));
但他们都给了我

无法强制转换类型为的对象 'System.Collections.Generic.List`1[Abc.Shared.Models.Location]'到 键入'System.Collections.Generic.List'1[System.Object]'

猜想:既然我不能直接调用ReadJson,我可以通过指定泛型“t”类型的反射调用ReadJson吗?我不知道这是否可能

(为了完整起见,这里是通用方法——我认为问题不在这里)

publicstaticlist ReadJson(字符串文件路径,类型t),其中t:class,new()
{
列表区域=新列表();
使用(StreamReader file=System.IO.file.OpenText(filePath))
{
JsonSerializer serializer=新的JsonSerializer();
区域=(列表)序列化程序。反序列化(文件,t);
}
返回区;
}
尝试以下操作:

public static List<T> ReadJson<T>(string filePath)
{
    using (var reader = File.OpenText(filePath))
    {
        var serializer = new JsonSerializer();
        return (List<T>) serializer.Deserialize(reader, typeof(List<T>));
    }
}

public static IList ReadJson(string filePath, Type itemType)
{
    using (var reader = File.OpenText(filePath))
    {
        var serializer = new JsonSerializer();
        var type = typeof(List<>).MakeGenericType(itemType);
        return (IList)serializer.Deserialize(reader, type);
    }
}
公共静态列表ReadJson(字符串文件路径)
{
使用(var reader=File.OpenText(filePath))
{
var serializer=new JsonSerializer();
返回(列表)序列化程序。反序列化(读取器,typeof(列表));
}
}
公共静态IList ReadJson(字符串文件路径,类型itemType)
{
使用(var reader=File.OpenText(filePath))
{
var serializer=new JsonSerializer();
var type=typeof(列表)。MakeGenericType(itemType);
返回(IList)序列化程序。反序列化(读取器,类型);
}
}
如果在设计时知道项目类型,则可以使用第一个版本。如果在设计时不知道项目类型,但在运行时知道,则可以使用第二个版本。在任何情况下,这两种方法都会返回
itemType/T
项的列表

第二个版本声明为返回
IList
。这就是我们所能做的,因为我们在设计时不知道项目类型。但是,它返回一个真正的
列表

您的
ReadJson
方法是多余的,如果您知道
T
,那么您就知道
T
,因为
T=typeof(T)
。或者您的意思是
t=typeof(List)
您不能将
List
强制转换为
List
(并且
对象是所有引用类型的基础),因为
List
是不协变的。您可以将
IEnumerable
强制转换为
IEnumerable
,因为
IEnumerable
是,因此,您可以将
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());
public static IEnumerable ReadJson1(字符串文件路径,类型t),其中t:class,new()
{
IEnumerable regions=新列表();
使用(StreamReader file=System.IO.file.OpenText(filePath))
{
JsonSerializer serializer=新的JsonSerializer();
regions=(IEnumerable)序列化程序。反序列化(文件,t);
}
返回区;
}
公共静态T[]ReadJson2(字符串文件路径,类型T),其中T:class,new()
{
使用(StreamReader file=System.IO.file.OpenText(filePath))
{
JsonSerializer serializer=新的JsonSerializer();
var regions=(T[])序列化程序。反序列化(文件,T);
返回区;
}
}
类型=类型(MyObject);
IEnumerable k1=ReadJson1(“test.json”,typeof(List).MakeGenericType(new[]{type}));
object[]k2=ReadJson2(“test.json”,type.MakeArrayType());

您的
k
变量是什么数据类型?请尝试返回
IEnumerable
。您不能将
列表
转换为
列表
,但您可以将
IEnumerable
转换为
IEnumerable
谢谢@xanatos-如果您回答这个问题,我会将其标记为解决方案。
public static List<T> ReadJson<T>(string filePath)
{
    using (var reader = File.OpenText(filePath))
    {
        var serializer = new JsonSerializer();
        return (List<T>) serializer.Deserialize(reader, typeof(List<T>));
    }
}

public static IList ReadJson(string filePath, Type itemType)
{
    using (var reader = File.OpenText(filePath))
    {
        var serializer = new JsonSerializer();
        var type = typeof(List<>).MakeGenericType(itemType);
        return (IList)serializer.Deserialize(reader, type);
    }
}
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());