如何创建动态类型List <t> </t>

时间:2012-03-25 13:14:46

标签: c# .net reflection

我不希望我的列表是固定类型。相反,我希望List的创建依赖于变量的类型。此代码不起作用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Generic;
namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {

            string something = "Apple";

            Type type = something.GetType();

            List<type> list = null;

            Console.ReadKey();

        }
    }
}

有人能告诉我需要做些什么改变才能让它正常工作吗?我希望list的创建取决于变量something

的类型

4 个答案:

答案 0 :(得分:35)

string something = "Apple";
Type type = something.GetType();
Type listType = typeof(List<>).MakeGenericType(new [] { type } );
IList list = (IList)Activator.CreateInstance(listType);

这是您创建静态未知类型列表的方法。但请注意,您无法静态提及列表的运行时类型。您必须使用非泛型类型甚至对象。

在不了解您想要完成的任务的情况下,这是您能做的最好的事情。

答案 1 :(得分:6)

  

我想要类型安全,但我需要动态类型安全。

如果您的意思是希望运行时类型安全,可以使用反射(请参阅usr的答案)或List<T>创建dynamic,然后将其视为非通用IList。< / p>

使用dynamic,它看起来像这样:

static List<T> CreateListByExample<T>(T obj)
{
    return new List<T>();
}

…

object something = "Apple";

IList list = CreateListByExample((dynamic)something);

list.Add(something); // OK

list.Add(42);        // throws ArgumentException

答案 2 :(得分:1)

动态和反射都很好 - 但性能下降 - 失去强打字,代码设计/清晰度等。
即。你应该总是试着用它来解决问题 - 如果可以的话,你的代码允许它...
所以,并且(注意)依赖于(非常)您的特定代码,需要,
您还可以使用“技巧”来“推断”该类型并使其成为通用 ......

class Program
{
    static void Main(string[] args)
    {
        string something = "Apple";
        int test = 5;
        var list = something.GetList();
        var listint = test.GetList();
        Console.WriteLine(list.GetType());
    }
}
static class Extension
{
    public static List<T> GetList<T>(this T value)
    {
        return new[] { value }.ToList();
    }
}

...即。如果你有一个变量的值,在'输入'通用上下文之前,
你可以使用扩展(这对此很有帮助), 并让它推断出你的类型和列表类型 注意:遗憾的是,这种“解决方法”并不总是很明显,而且当你的代码“过于动态”时(我知道这不是太'精确'但超出了这个范围),如果它取决于反射引起的类型等。
也就是说,没有一个干净利落的解决方案,这只是一个例子,你需要为它添加一些汗水:)以使它适合你 - 例如你可能需要一个包装器类型,显然以这种方式创建一个列表可能不是你想要的等等。

答案 3 :(得分:0)

编译器必须在编译时知道泛型类型T.所以不,你真的不能这样做。