C# 如何创建动态类型 List<T>

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9860387/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 10:57:57  来源:igfitidea点击:

How do I create a dynamic type List<T>

c#.netreflection

提问by Jaggu

I don't want my List to be of fixed type. Rather I want the creation of List to be dependent on the type of variable. This code doesn't work:

我不希望我的 List 是固定类型的。相反,我希望 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();

        }
    }
}

Can anybody tell me what changes I need to make in order to make it work right? I want the creation of listto be dependent on the type of variable something

谁能告诉我需要进行哪些更改才能使其正常工作?我希望的创建list依赖于变量的类型something

采纳答案by usr

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

This is how you create a list of statically unknown type. But notice that you are unable to mention the runtime type of the list statically. You have to use a non-generic type or even object.

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

Without knowing more about what you want to accomplish this is the best you can do.

在不了解更多关于你想要完成的事情的情况下,这是你能做的最好的事情。

回答by Erix

The compiler must know the generic type T at compile time. So no, you can't really do this.

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

回答by svick

I want type safety but I need dynamic type safety.

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

If you mean you want runtime type-safety, you can create List<T>using reflection (see usr's answer) or dynamicand then treat it as the non-generic IList.

如果您的意思是想要运行时类型安全,则可以List<T>使用反射创建(请参阅 usr 的答案),或者dynamic然后将其视为非泛型IList.

Using dynamic, it would look something like this:

使用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

回答by NSGaga-mostly-inactive

The dynamic and reflection all work fine - but with a downside on performance - and losing strong typing,code design / clarity etc.
i.e. you should always try and resolve things w/o it- if you can, your code allows it...
So, and (note) depending (very much) on your specific code, needs,
you could also use a 'trick' to 'infer' the type and make it generic...

动态和反射都可以正常工作 -但有性能上的缺点 - 并失去强类型,代码设计/清晰度等。
也就是说,您应该始终尝试解决没有它的问题-如果可以,您的代码允许...
因此,并且(注意)(非常取决于您的特定代码、需求,
您还可以使用“技巧”来“推断”类型并使其通用......

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();
    }
}

...i.e. if you have a value for a variable and before 'entering' the generic context,
you could use extensions (which are very helpful with around this), and let it infer the type and a list type for you
NOTE: this 'work around' unfortunately doesn't always pan out and when your code is 'too dynamic' (I know this is not too 'exact' but out of scope for this) and if it's depending on the reflection induced types etc.
i.e. there isn't a clean-cut solution, this is just an example, you'd need to put some sweat into it :) to make it work for you - e.g. you may require a wrapper type here and there and obviously creating a list in this way might not be what you want etc.

...即如果您有一个变量的值并且在“输入”通用上下文之前,
您可以使用扩展(这对解决此问题非常有帮助),并让它为您推断类型和列表类型
注意:这个不幸的是,“变通”并不总是成功,并且当您的代码“太动态”时(我知道这不是太“精确”,但超出了范围)并且它是否取决于反射诱导类型等。
即有不是一个干净的解决方案,这只是一个例子,你需要付出一些汗水:) 让它为你工作 - 例如,你可能需要一个包装器类型在这里和那里显然创建一个列表这种方式可能不是你想要的等等。