2009-08-21 18 views
9

Estoy tratando de convertir List<object> en List<string> dinámicamente. Lo intenté de varias maneras, pero no puedo encontrar una solución. Esta es una pequeña muestra que muestra el problema:¿Cómo emitir listas genéricas dinámicamente en C#?

List<object> listObject = new List<object>(); 
listObject.Add("ITEM 1"); 
listObject.Add("ITEM 2"); 
listObject.Add("ITEM 3"); 

List<string> listString = ¿¿listObject??; 

¡Gracias de antemano!

+8

Esto no será posible en la versión 4 o bien, porque no se Typesafe a cualquiera "conversión hacia arriba" o "abatido" una 'lista ' - que es invariante, no covariantes contravariante. Por cierto, me estoy cansando de que esta desinformación se publique en todas las preguntas sobre co-contravariación de la colección. –

Respuesta

18

Si puede utilizar LINQ entonces el método Cast hará lo que usted necesita:

List<string> listString = listObject.Cast<string>().ToList(); 

también puede utilizar el método ConvertAll, como señala Stan en su respuesta:

List<string> listString = listObject.ConvertAll(x => (string)x); 

Si no estás usando C# 3, entonces necesitarás usar la sintaxis de delegado "vieja" en lugar de una lambda:

List<string> listString = 
    listObject.ConvertAll(delegate(object x) { return (string)x; }); 
+0

+1 para el uso correcto del delegado sytnax :) –

+1

@nader: Siempre trato de recordar que cuando LINQ no está disponible, tampoco lo es la sintaxis lambda. – LukeH

+0

+1 buen punto Luke –

4

Si está usando .NET 3.5 puede usarlo, de esta manera no tiene que hacer una ToList() adicional. También puede suministrar su propio convertidor si necesita convertir objetos avanzados.

List<string> listString = listObject.ConvertAll(x=> x as String); 

Si no puede utilizar LINQ puede hacerlo

foreach(object item in listObject) 
{ 
    string convertedItem = item as String; 
    if(convertedItem != null) 
     listString.Add(convertedItem); 
} 
+1

Esto también es compatible con .NET 2.0 (sin LINQ, aunque la sintaxis de delgate no es tan buena). Sin embargo, una nota, no creo que el .Cast .ToList() creará una lista "extra" como está implicando. Creará una nueva lista, para el resultado, al igual que su enfoque –

+0

Creo que se refiere a C# 3.0 y .Net 3.5. – user7116

+0

eso es lo que quise decir. Gracias. –

0

no creo que pueda hacerlo solo paso. En su lugar, intentar algo como esto:

 List<object> listObject = new List<object>(); 
     listObject.Add("ITEM 1"); 
     listObject.Add("ITEM 2"); 
     listObject.Add("ITEM 3"); 

     List<string> lstStr = new List<string>(listObject.Count); 

     foreach (object obj in listObject) 
     { 
      lstStr.Add(obj.ToString()); 
     } 
+0

esto es incorrecto, no quiere toc todo ToString() en ese objeto, quiere convertirlo en un objeto de cadena. Técnicamente, su ejemplo funcionará esta vez, pero solo para cadenas. Pero si choca con un objeto más avanzado, no podrá usar este método. –

+0

Se puede hacer en un solo paso, consulte las otras respuestas ... –

0
List<string> listString = (from o in listObject select (string)o).ToList(); 
+1

Consulte 'Enumerable.Cast ()'. –

1

Como tal esto:

public static List<T> ConvertToGenericList<T>(IList listOfObjects) 
{ 
    List<T> items = new List<T>(); 

    for (int i = 0; i < listOfObjects.Count; i++) 
    { 
     items.Add((T)listOfObjects[i]); 
    } 
    return items; 
} 

Uso:

List<object> listObject = new List<object>(); 
listObject.Add("ITEM 1"); 
listObject.Add("ITEM 2"); 
listObject.Add("ITEM 3"); 
List<string> listString = Converter.ConvertToGenericList<string>(listObject); 
-2

Mi primer post ... La esperanza se ve muy útil trabajar en mi proyecto ...

 public dynamic ConvertList(Type CallingType) 
    { 

     dynamic DynamicList; 

     if (CallingType == TypeOfValue) 
     { 
      Type d1 = typeof(List<>); 

      Type[] typeArgs = { TypeOfValue }; 

      Type DynamicListType = d1.MakeGenericType(typeArgs); 


      object DynamicListObj = Activator.CreateInstance(DynamicListType); 


      DynamicList = Convert.ChangeType(DynamicListObj, DynamicListType); 


      foreach (object ValueElement in ValueRange) 
      { 
        dynamic el = Convert.ChangeType(ValueElement, TypeOfValue); 
        DynamicList.Add(el); 
      } 

     } 
     else //retrun empty List but with right type 
     { 
      Type d1 = typeof(List<>); 

      Type[] typeArgs = { CallingType }; 

      Type DynamicListType = d1.MakeGenericType(typeArgs); 

      object DynamicListObj = Activator.CreateInstance(DynamicListType); 

      DynamicList = Convert.ChangeType(DynamicListObj, DynamicListType); 
     } 

     return DynamicList; 
    } 

Creo que agregaré también una captura de prueba en alguna parte.

cómo probar

   if (PropertyType == typeof(UInt32)) 
       { 
        List<UInt32> UInt32_test = NewProperty.ConvertList(PropertyType); 
       } 
       if (PropertyType == typeof(string)) 
       { 

        List<string> string_test = NewProperty.ConvertList(PropertyType); 
       } 
Cuestiones relacionadas