我正在尝试使用Json.NET编写一种从json文件反序列化的通用方法,
我希望能够支持反序列化包含对象以及对象数组的文件。以下是我目前拥有的两种通用方法的简化版本:
/// <summary> Deserializes object or an array of objects from a list of files. </summary>
public static List<T> Deserialize<T>(List<string> filePathsList)
{
var result = new List<T>();
foreach (var file in filePathsList)
// HOW DO I FIND OUT IF T IS A LIST HERE?
// Resharper says: the given expression is never of the provided type
if (typeof(T) is List<object>)
{
var deserialized = Deserialize<List<T>>(file);
result.AddRange(deserialized);
}
// Resharper says: Suspicious type check: there is not type in the solution
// which is inherited from both 'System.Type' and 'System.Collections.IList'
else if (typeof(T) is IList)
{
// deserializing json file with an array of objects
var deserialized = Deserialize<List<T>>(file);
result.AddRange(deserialized);
}
else
{
// deserializing a single object json file
var deserialized = Deserialize<T>(file);
result.Add(deserialized);
}
return result;
}
/// <summary> Deserializes object or an array of objects from a file. </summary>
public static T Deserialize<T>(string filepath)
{
return JsonConvert.DeserializeObject<T>(File.ReadAllText(filepath));
}
问题是,在反序列化之前,我需要知道T是对象还是对象列表。如何在通用方法中检查?因为resharper会给我警告,而我似乎无法弄清楚。
编辑:我在示例代码中犯了一个错误,正如@ Medo42指出的那样,它将使用De调用Deserialize()。List<List<Something>>
另外,我根本不应该包含一个涉及json序列化的示例,它应该更通用。问题是要找出T是否是对象列表。
在此先感谢您的帮助。
这不是一个完整的答案,但是评论太长,可能有助于您更好地理解某些问题。
// Resharper says: the given expression is never of the provided type
if (typeof(T) is List<object>)
Resharper是对的。该is
运营商检查左边的实例是否是正确的类型,所以在你的情况下,它会检查,如果typeof(T)
是的一个实例List<object>
。但是,typeof(T)
返回一个代表的类型的Type
实例。正确的检查方式(如果您使用的是确切类型)是T
if (typeof(T) == typeof(List<object>))
但要注意的是,如果这仅适用T
是完全相同 List<object>
。如果还可以有的子类型List<object>
,则该行为
if (typeof(List<object>).IsAssignableFrom(typeof(T)))
但是,您的问题并不止于此。您似乎假设这List<object>
是所有列表的超类型。即使不是这样,即使我们可以假设我们只会使用List<T>
列表的实现。这样做的原因List<T>
是不变的。
不变性意味着猫的列表不是哺乳动物的列表。如果这似乎违反直觉,那是因为您将列表视为要从中读取的固定集合。但是,您也可以将新项目添加到C#列表中,如果允许您将aList<Cat>
视为a List<Mammal>
,则可能最终尝试将大象添加到该列表中,这不会给仍然持有a的其他人带来混乱将该列表作为引用List<Cat>
。
对于类型检查问题的解决方案,我认为drf对dotctor答案的评论是做您想做的事情的最干净的方法:
typeof(T).GetGenericTypeDefinition() == typeof(List<>)
最后,下面的代码看起来也很奇怪:
var deserialized = Deserialize<List<T>>(file);
在确定T
确实是a之后List<Something>
,您可以执行此操作,因此现在尝试将文件反序列化为a List<List<Something>>
,这可能不是您想要的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句