2009-08-21 7 views
9

Ich versuche, List<object> zu List<string> dynamisch zu übertragen. Ich habe mehrere Möglichkeiten ausprobiert, aber ich kann keine Lösung finden. Dies ist ein kleines Beispiel, das das Problem zeigt:Wie generische Listen dynamisch in C# umgewandelt werden?

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

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

Vielen Dank im Voraus!

+8

Dies wird 4 entweder in Version nicht möglich sein, weil es nicht zu ist typsicher entweder „upcast“ oder „gesenkten“ a 'Liste ' - es ist unveränderlich, nicht kovariant oder kontravariant. Übrigens habe ich genug von dieser Fehlinformation, die auf jede Frage über die Sammlungs- und Kontravarianz gestellt wird. –

Antwort

18

Wenn Sie LINQ dann die Cast Methode verwenden kann, wird das tun, was Sie brauchen:

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

Sie können auch die ConvertAll Methode verwenden, wie Stan in seiner Antwort weist darauf hin:

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

Wenn Wenn Sie nicht C# 3 verwenden, müssen Sie statt eines Lambda die "alte" Delegatensyntax verwenden:

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

+1 für die korrekte Verwendung von Delegaten sytnax :) –

+1

@NADER: Ich versuche immer daran zu erinnern, dass, wenn LINQ nicht verfügbar ist, dann ist weder Lambda-Syntax. – LukeH

+0

+1 guter Punkt Luke –

4

Wenn Sie .NET 3.5 verwenden, können Sie auf diese Weise keine zusätzliche ToList() erstellen. Sie können auch einen eigenen Konverter bereitstellen, wenn Sie erweiterte Objekte konvertieren müssen.

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

Wenn Sie nicht LINQ verwenden, können Sie dieses tun

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

Dies wird auch in .NET 2.0 unterstützt (ohne LINQ, obwohl die Delgate-Syntax nicht so schön ist). Eine Anmerkung, ich glaube nicht, dass die .Cast .ToList() wird eine "extra" -Liste erstellen, wie Sie implizieren. Es wird eine neue Liste für das Ergebnis erstellen, wie auch Ihr Ansatz –

+0

Ich denke, Sie meinen C# 3.0 und .Net 3.5. – user7116

+0

das ist was ich meinte. Vielen Dank. –

0

Das glaube ich nicht, dass Sie es einen Schritt tun können. Stattdessen versuchen, etwas wie folgt aus:

 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

das ist falsch, er will nicht alle ToString() auf diesem Objekt, er will es in ein String-Objekt konvertieren. Technisch wird dieses Beispiel diesmal funktionieren, aber nur für Strings. Aber wenn er zufällig auf ein fortgeschritteneres Objekt trifft, kann er diese Methode nicht anwenden. –

+0

Es kann in einem Schritt erfolgen, siehe die anderen Antworten ... –

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

Siehe 'Enumerable.Cast ()'. –

1

Wie dieser Kampf:

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

Verbrauch:

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

Mein erster Beitrag ... Hoffnung nützlich schaut in meine Projektarbeit ...

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

Ich denke, dass ich irgendwo auch einen Versuch fangen werde.

, wie Sie testen

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

        List<string> string_test = NewProperty.ConvertList(PropertyType); 
       } 
Verwandte Themen