我正在实现某种反序列化,并且遇到了下一个问题:

我有List<object>System.Reflection.Field,它的FieldType可以是List<string>List<int>List<bool>,所以我需要从List<object>转换为该类型。

public static object ConvertList(List<object> value, Type type)
{
   //type may be List<int>, List<bool>, List<string>
}

我可以分别编写每种情况,但是应该有使用反射的更好方法。

最佳答案

我相信您想要的是:

public static object ConvertList(List<object> value, Type type)
{
    var containedType = type.GenericTypeArguments.First();
    return value.Select(item => Convert.ChangeType(item, containedType)).ToList();
}

用法示例:
var objects = new List<Object> { 1, 2, 3, 4 };

ConvertList(objects, typeof(List<int>)).Dump();

我不确定这到底有多有用...它突显了我猜是非常有用的Convert.ChangeType方法!

更新:由于其他人正确地指出这实际上不会返回List<T>(其中T是所讨论的类型),因此可能无法完全回答当前的问题,因此我选择提供更新的答案:
public static object ConvertList(List<object> items, Type type, bool performConversion = false)
{
    var containedType = type.GenericTypeArguments.First();
    var enumerableType = typeof(System.Linq.Enumerable);
    var castMethod = enumerableType.GetMethod(nameof(System.Linq.Enumerable.Cast)).MakeGenericMethod(containedType);
    var toListMethod = enumerableType.GetMethod(nameof(System.Linq.Enumerable.ToList)).MakeGenericMethod(containedType);

    IEnumerable<object> itemsToCast;

    if(performConversion)
    {
        itemsToCast = items.Select(item => Convert.ChangeType(item, containedType));
    }
    else
    {
        itemsToCast = items;
    }

    var castedItems = castMethod.Invoke(null, new[] { itemsToCast });

    return toListMethod.Invoke(null, new[] { castedItems });
}

如果不需要转换(因此每个值的类型实际上是正确的,并且字符串中没有整数等),则删除performConversion标志和关联的块。

示例:https://dotnetfiddle.net/nSFq22

关于c# - 将List <object>转换为List <Type>,类型在运行时已知,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22939552/

10-17 02:12