Тип динамического списка <T>
Возможно ли создать новый List<T>
, где T динамически устанавливается во время выполнения?
Приветствия
Ответы
Ответ 1
Это возможно, но не обязательно полезно, поскольку вы не могли фактически использовать его из скомпилированного кода, как строго типизированного. Код создания будет
Type myType;
Type listType = typeof(List<>).MakeGenericType(myType);
IList myList = (IList)Activator.CreateInstance(listType);
Ответ 2
Да. Вы можете сделать это через Reflection, используя Type.MakeGenericType и Activator.CreateInstance.
IList MakeListOfType(Type listType)
{
Type listType = typeof(List<>);
Type specificListType = listType.MakeGenericType(listType);
return (IList)Activator.CreateInstance(specificListType);
}
Ответ 3
Да. Однако вы не сможете назначить его переменной, которая имеет общий тип, поскольку T в этом случае не будет определяться до времени выполнения. (Если вы думаете, что функция ковариации .NET 4.0 поможет вам и позволит вам объявить переменную как IList<SomeSuperType>
, она не будет использоваться, если T
используется List<T>
для in
и out
цели.)
Обратите внимание на необычный синтаксис List < > , чтобы получить доступ к "неконструированному" родовому типу.
public static System.Collections.IList ConstructGenericList(Type t)
{
return (System.Collections.IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(t));
}
Ответ 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
да с помощью generic вы можете сделать что-то вроде этого
var asd = METHOD<Button>();
List<t> METHOD<t>()
{
return new List<t>();
}