使用System.Type对象</object>转换List <object>

时间:2010-09-29 16:15:44

标签: .net list reflection

假设我使用反射检索了System.Type对象,并希望使用该类型将List<Object>转换为该类型的另一个列表。

如果我尝试:

Type type = GetTypeUsingReflection();
var myNewList = listObject.ConvertAll(x => Convert.ChangeType(x, type)); 

我得到一个异常,因为该对象没有实现IConvertible接口。有没有办法绕过这个或另一种方式来解决这个问题?

4 个答案:

答案 0 :(得分:4)

您建议的解决方案实际上无法正常工作 - 它只会创建另一个List<Object>,因为ChangeType的返回类型为Object

假设你只想要施法,你可以这样做:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;

class Test
{
    private static List<T> ConvertListImpl<T>(List<object> list)
    {
        return list.ConvertAll(x => (T) x);
    }

    // Replace "Test" with the name of the type containing this method
    private static MethodInfo methodDefinition = typeof(Test).GetMethod
        ("ConvertListImpl", BindingFlags.Static | BindingFlags.NonPublic);

    public static IEnumerable ConvertList(List<object> list, Type type)
    {
        MethodInfo method = methodDefinition.MakeGenericMethod(type);
        return (IEnumerable) method.Invoke(null, new object[] { list });
    }

    static void Main()
    {
        List<object> objects = new List<object> { "Hello", "there" };
        List<string> strings = (List<string>) ConvertList(objects,
                                                          typeof(string));

        foreach (string x in strings)
        {
            Console.WriteLine(x);
        }
    }
}

答案 1 :(得分:0)

当在设计时不知道类型时,投射很少使用。一旦将新的对象列表转换为新类型,您将如何使用新类型?您无法调用类型公开的方法(不使用更多反射)

答案 2 :(得分:0)

类型系统无法从存储类型T的类型变量转换为类型T的泛型参数。

从技术上讲,您可以创建正确类型的通用列表(使用反射),但在编译时类型信息不可用。

答案 3 :(得分:0)

Type type = typeof(int); // could as well be obtained by Reflection

var objList = new List<object> { 1, 2, 3 };
var intList = (IList) Activator.CreateInstance(
    typeof(List<>).MakeGenericType(type)
    );

foreach (var item in objList)
    intList.Add(item);

// System.Collections.Generic.List`1[[System.Int32, ...]]
Console.WriteLine(intList.GetType().FullName);

但为什么你需要地球?