2014-04-08 18 views
9

sto attuazione di alcune specie di deserializzazione e ha lottato con un problema:Lista Converti <object> to List <Type>, tipo è noto a tempo di esecuzione

ho List<object> e System.Reflection.Field, è FieldType può essere List<string>, List<int> o List<bool>, così ho è necessario convertire da List<object> a quel tipo.

public static object ConvertList(List<object> value, Type type) 
{ 
    //type may be List<int>, List<bool>, List<string> 
} 

posso scrivere ogni caso separatamente, ma ci dovrebbe essere un modo migliore utilizzando la riflessione.

risposta

7

Credo che ciò che si vuole è :

public static object ConvertList(List<object> value, Type type) 
{ 
    var containedType = type.GenericTypeArguments.First(); 
    return value.Select(item => Convert.ChangeType(item, containedType)); 
} 
0 utilizzo

Esempio:

var objects = new List<Object> { 1, 2, 3, 4 }; 

ConvertList(objects, typeof(List<int>)).Dump(); 

Non sono sicuro di quanto sia utile questo è però ... Si mette in evidenza il metodo Convert.ChangeType follemente utile immagino!

+0

Il metodo restituisce un oggetto IEnumerable non un elenco . Potrei aver frainteso la domanda. – Guillaume

0

Prova questo:

public static List<T> ConvertList<T>(List<object> list) 
{ 
    List<T> castedList = list.Select(x => (T)x); 
    return castedList; 
} 

chiamata:

List<object> myList = new List<object> {"test", "foo", "bar"}; 
List<string> stringList = ConvertList<string>(myList); 
+0

come posso capire che dovrei chiamare ConvertList ? Conosco solo il tipo, non riesco a digitare ConvertList

+0

Oh, mi dispiace, sto modificando la mia risposta. –

0
public static List<T> ConvertType<T>(List<object> list) { 
    var list2 = new List<T>(); 
    for(int i=0;i<list.Count;i++) list2.Add((T)list[i]); 
    return list2; 
} 
+0

come posso capire che dovrei chiamare ConvertList ? Conosco solo Type, non riesco a digitare ConvertList

+0

Vedo, quindi sarà necessario utilizzare reflection per rendere il tipo generico in fase di esecuzione, vedere la risposta di Guillaume (che non ripeterò). – kevin

1

Non sono sicuro se questo aiuta a tutti, ma si può usare LINQ cast?

List<object> theList = new List<object>(){ 1, 2, 3}; 
List<int> listAsInt = theList.Cast<int>(); 
1
public static object ConvertList<T>(List<object> value) where T : class 
    { 
     var newlist = value.Cast<T>().ToList(); 
     return newlist; 
    } 

o

public static List<T> ConvertList<T>(List<object> value) where T : class 
    { 
     List<T> newlist = value.Cast<T>().ToList(); 
     return newlist; 
    } 
8

Il tipo è conosciuta solo in fase di esecuzione in modo da indovino metodo generico non è la strada da percorrere

public static object ConvertList(List<object> value, Type type) 
{ 
    IList list = (IList)Activator.CreateInstance(type); 
    foreach (var item in value) 
    { 
     list.Add(item); 
    } 
    return list; 
} 
+0

sì, è una bella soluzione. Trovato buon thread qui -http: //stackoverflow.com/questions/2474119/dynamic-listt-type –

+0

Non sono sicuro che funzionerà per i tipi che l'OP ha menzionato (almeno bool e int) perché creare un elenco di oggetti in primo luogo i tipi di valore sono stati inseriti in una scatola e quindi non possono essere aggiunti alla lista. Modifica: in realtà non è questo il problema. Devi cambiare 'Type [] typeArgs = {type};' nel tuo metodo per 'Type [] typeArgs = {type.GenericTypeArguments.First()};'; – Richiban

+0

@Richiban hai ragione, mi sono sbagliato a pensare che 'type' fosse il tipo di articolo. Risolto il problema – Guillaume

0
/// <summary> 
    /// Converts list of items into typed list of item of new type 
    /// </summary> 
    /// <example><code> 
    /// Consider source to be List<object>, newItemType is typeof(string), so resulting list wil have type List<string> 
    /// </code></example> 
    /// <param name="newItemType">New item type</param> 
    /// <param name="source">List of objects</param> 
    /// <returns>Typed List object</returns> 
    public static IList ConvertList(Type newItemType, IList source) 
    { 
     var listType = typeof(List<>); 
     Type[] typeArgs = { newItemType }; 
     var genericListType = listType.MakeGenericType(typeArgs); 
     var typedList = (IList)Activator.CreateInstance(genericListType); 
     foreach (var item in source) 
     { 
      typedList.Add(item); 
     } 
     return typedList; 
    }