将对象(List <string>)转换为List <object>

时间:2019-06-25 14:37:57

标签: c#

我正在尝试编写一个用于REST-API测试的小型框架。我进行了很多反思,遇到了一个我无法解决的问题。

我使用此行提取用户给我的变量作为路径(字符串)

object o = input.GetType().GetProperty(name).propertyInfo.GetValue(input, null);

该对象可以是普通类型TList<T>。 现在,如果它是一个List并且我知道类型很简单,那么我可以使用

List<string> l = (List<string>)o; // I know its a List<string> because the user told me

将对象解析为给定数组。但是我并不总是知道列表中对象的类型,并且

List<object> l = (List<object>)o; // I dont know the type and I dont care

给我一​​个错误。

  

类型为“ System.Collection.GenericList [System.String]”的对象不能   转换为“ System.Collection.GenericList [System.Object]”

我可以做些什么来接收对象列表吗?我不希望用户指定类型,因为它只是我要关心的最后一个变量。喜欢

用户想要测试“ object1.a.b.c”,我只需要知道c的类型,因为那是测试运行的地方。

TIA

2 个答案:

答案 0 :(得分:7)

您可以将其转换为IEnumerable<object>,但不能转换为List<object>。原因是:香蕉列表不是水果列表,因为您可以将苹果放入水果列​​表中,但不能放入香蕉列表中。由于这两种类型允许不同的操作,所以它们不兼容。

一个序列没有“放入”操作,因此可以使用香蕉列表作为水果的一个序列。同样,您可以将字符串列表用作对象的序列,但不能用作对象的 list

此功能称为通用协方差;有关更多信息,请搜索C#协方差,您会发现很多文章解释其工作原理。

尤其要注意协方差仅适用于引用类型;您不能将整数序列用作对象序列。你知道为什么吗?

或者,如果您手头有一个IEnumerable,则可以使用mysequence.Cast<object>().ToList() any 序列的副本复制到对象列表中。但这是副本,而不是参考转换。

答案 1 :(得分:1)

由于您的问题开始于处理以JSON形式到达服务器的动态对象,因此在转换为POCO之前,使用JSON处理库本身来测试某些特征非常方便。使用newtonsoft的JSON.Net,

var o = JObject.Parse(json);
JToken property = o["a"]["b"]["c"];
if (property != null)
{
    if (property.Type == JTokenType.Array)
    {
      // Process property as array

    }
    else if  (property.Type == JTokenType.Object)
    {
      // Process property as object
    }
    // Magnitude of other types
}

我确实了解在最终处理之前需要转换为.NET类型的需求,但是我强烈建议从JObjects开始,因为该库是为此目的而设计的,并且为C#本身没有提供的许多动态操作提供了许多便利的方法。