将(本地)变量作为Type传递给泛型方法

时间:2016-06-27 09:13:04

标签: c# generics

我想做什么,非常短的版本 总结:

var localType = typeof(MyDTOClass);
var result = MyGenericMethod<localType>(string path);

VisualStudio告诉我 dtoType是可变的,但是像类型一样使用。

长版: 我有以下字典,用于从磁盘读取一些文件,然后使用(反)序列化器将其转换为对象。 json文件的内容几乎相同,所以我只把一个作为例子: Json内容,对象数组:

[{
"id": "1",
"areaType": "2",
"backgroundImagePath": "path",}, {
"id": "2",
"areaType": "2",
"backgroundImagePath": "path",}, {
"id": "99",
"areaType": "1",
"backgroundImagePath": "path",}]

字典内容:

var filesToParse = new Dictionary<string, Type>{
    { "area.json",typeof(AreaDto) },
    { "areaObject.json",typeof(AreaObjectDto) },
    { "monsterSymbol.json",typeof(MonsterSymbolDto) },
};

检索json内容的代码:

IEnumerable GetDeserializedJson(string pathToJsonFile, Type dtoType) {
    IEnumerable result;
    using (TextReader file = File.OpenText(pathToJsonFile)) {
    result = JsonSerializer.DeserializeFromReader<IEnumerable<dtoType>>(file);
    }
    return result.OfType<dtoType>.Where(x => x != null);
}

我的问题是以下几行

result = JsonSerializer.DeserializeFromReader<dtoType>(file);
result.OfType<dtoType>.Where(x => x != null);

dtoType是可变的,但是像类型一样使用。我知道它是一个变量,但它是Type的一个变量。你能解释一下为什么我不能通过这个类型的变量,如果可能的话,如何进一步解决我的问题。 以下是我(想)调用我的GetDeserializedJson

的方法
foreach(var keyValuePair in filesToParse){
    GetDeserializedJson<keyValuePair.Value>(keyValuePair.Key);
}

提前致谢

2 个答案:

答案 0 :(得分:2)

只需使用非通用DeserializeFromReader(reader, Type)方法,它就会返回object。 像这样:

result = JsonSerializer.DeserializeFromReader(file, typeof(dtotype));

dtoTypeType的实例,只需

result = JsonSerializer.DeserializeFromReader(file, dtotype);

答案 1 :(得分:1)

您必须决定是否要使用泛型或类型,但不能动态“切换”到泛型。 说到这个例子

var localType = typeof(MyDTOClass);
var result = MyGenericMethod<localType>(string path);

你不需要第一行,而应该是

 var result = MyGenericMethod<MyDTOClass>(string path);

说到其他样本

IEnumerable GetDeserializedJson(string pathToJsonFile, Type dtoType) 
{
     IEnumerable result;
     using (TextReader file = File.OpenText(pathToJsonFile)) 
     {
          result = JsonSerializer.DeserializeFromReader<IEnumerable<dtoType>>(file);
     }
     return result.OfType<dtoType>.Where(x => x != null);
}

您可以改为声明泛型方法:

IEnumerable<TDto> GetDeserializedJson<TDto>(string pathToJsonFile) where TDto : DtoBaseClass
{
     IEnumerable<TDto> result;
     using (TextReader file = File.OpenText(pathToJsonFile)) 
     {
          result = JsonSerializer.DeserializeFromReader<IEnumerable<TDto>>(file);
     }
     return result.OfType<TDto>.Where(x => x != null);
}

通过这种方式,您甚至不必强制转换为类型,并且您具有约束where TDto : DtoBaseClass,因此编译器将不允许您使用类,而不是从您的基础dto类派生。