【问题标题】:Dynamic List<T> type [duplicate]动态列表<T>类型[重复]
【发布时间】:2011-01-29 06:26:55
【问题描述】:

是否可以创建一个新的List&lt;T&gt;,其中 T 在运行时动态设置?

干杯

【问题讨论】:

    标签: c# .net dynamic


    【解决方案1】:

    这是可能的,但不一定有用,因为您实际上无法从编译代码中将其用作强类型。创建代码将是

        Type myType;
        Type listType = typeof(List<>).MakeGenericType(myType);
        IList myList = (IList)Activator.CreateInstance(listType);
    

    【讨论】:

    • 请注意“强类型”和“静态类型”之间存在差异。您在这里失去了静态类型检查,但 myList 会阻止您添加不是有效 myType 实例的对象。
    • @Lee,感谢您的澄清。
    • 这对我非常有用,因为我正在编写一个完全动态的数组/列表类型转换器。谢谢!
    • 如果你创建一个“UseAs(T obj)”方法并通过反射调用它并将类型作为参数传递,你可以使用它强类型。然后在里面你可以做任何事情。也许使它成为一种本地方法并捕获您的外部范围?或者..传递一个回调。只能说,有可能。我为此亲自制作了一个库。
    【解决方案2】:

    是的。您可以通过反射,使用Type.MakeGenericTypeActivator.CreateInstance 来做到这一点。

    IList MakeListOfType(Type listType)
    {
        Type listType = typeof(List<>);
        Type specificListType = listType.MakeGenericType(listType);
    
        return (IList)Activator.CreateInstance(specificListType);
    }
    

    【讨论】:

    • 你有一个参数 listType 和一个本地字段 listType,我想有些人会对此感到困惑(我没有投反对票)
    【解决方案3】:

    是的。但是,您将无法将其分配给具有泛型类型的变量,因为在这种情况下,T 直到运行时才会确定。 (如果您认为 .NET 4.0 协方差特性会对您有所帮助,并让您将变量声明为 IList&lt;SomeSuperType&gt;,则它不会因为 List&lt;T&gt;inout 都使用 T目的。)

    注意不寻常的 List 语法,以便访问“未构造的”泛型类型。

        public static System.Collections.IList ConstructGenericList(Type t)
        {
            return (System.Collections.IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(t));
        }
    

    【讨论】:

    • (重新变体;也仅适用于接口/委托;不适用于类)
    • @Marc,对...我应该写IList&lt;SomeSuperType&gt;。修复。
    【解决方案4】:

    对于 DataContractSerializer 已知类型,您可能不仅需要提供程序集中的类型,还需要提供这些类型的列表:

    public static List<Type> GetKnownTypesForDataContractSerializer()
    {
        Assembly a = Assembly.GetExecutingAssembly();
        Type[] array = a.GetExportedTypes();
    
        List<Type> lista = array.ToList();
    
        lista = lista.FindAll(item => ((item.IsClass || item.IsEnum) & !item.IsGenericType & !item.IsAbstract == true));
    
    
    
        List<Type> withEnumerable = new List<Type>();
        foreach (Type t in lista)
        {
            withEnumerable.Add(t);   //add basic type
    
            //now create List<> type
            Type listType = typeof(List<>);
            var listOfType = listType.MakeGenericType(t);
    
            withEnumerable.Add(listOfType);  //add Type of List<basic type>  
        }
    
        return withEnumerable;
    }
    

    【讨论】:

      【解决方案5】:

      是的,使用泛型你可以做这样的事情

          var asd = METHOD<Button>();
      
          List<t> METHOD<t>()
          {
              return new List<t>();
          }
      

      【讨论】:

      • “按钮”类型是硬编码的,不是运行时
      • OP 要求在运行时确定 t。在您的示例中,它在编译时设置。
      猜你喜欢
      • 2020-08-05
      • 1970-01-01
      • 1970-01-01
      • 2019-03-08
      • 2012-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多