2016-08-12 2 views
1

Ich habe eine Methode, die als Argument einen generischen Typ T verwendet. Wenn T von Typ List ist, möchte ich es in eine Liste umwandeln, in der Y steht die Art von Element, das in T enthalten ist. Ich vermute, dass ich die Beschränkungen der generischen Typen falsch verstehe, aber jede Hilfe würde geschätzt werden.Wie man einen generischen Typ T in eine Liste eines bestimmten Typs umwandelt

Beispiel:

public void MapData<T>(T genericData) 
{ 
    var genericDataType = genericData.GetType(); 

    if (genericDataType.Name.Contains("List")) 
    { 
     //Cast T to a List containing the type of elements contained in T 
    } 
} 

Ich brauche genericData auf eine Liste zu werfen, so dass es in eine andere Methode mit der Signatur passieren kann:

public void MapListToField<T>(List<T> genericList) 

UPDATE

Per Eric Antwort unten wollte ich einen Versuch teilen, dass vielleicht jemand meinen Fehler aufzeigen könnte. Der Compiler wird die besagt, dass ich eine Variable als Typ zu verwenden versucht bin, die ich die Bedeutung verstehen, aber element ist ein Typ, also bin ich nicht klar, wie zu beheben:

var elementType = genericData.GetType().GetGenericArguments()[0]; 
var castedList = genericData as List<elementType>; 

Antwort

0

EDIT: Ist das nahe zu was du fragst?

Code:

void Main() 
{ 
    List<string> stringlist = new List<string> { "a", "b", "c" }; 
    List<int> intlist = new List<int> { 1, 2, 3 }; 
    string notList = ""; 
    var expression = Expression.Call(typeof(Methods), "CastToList", new Type[] { stringlist.GetType(), stringlist.GetType().GetGenericArguments()[0] }, Expression.Constant(stringlist)); 
    Expression.Lambda<Func<bool>>(expression).Compile()(); 
    expression = Expression.Call(typeof(Methods), "CastToList", new Type[] { intlist.GetType(), intlist.GetType().GetGenericArguments()[0] }, Expression.Constant(intlist)); 
    Expression.Lambda<Func<bool>>(expression).Compile()(); 
    expression = Expression.Call(typeof(Methods), "CastToList", new Type[] { notList.GetType(), typeof(object) }, Expression.Constant(notList)); 
    Expression.Lambda<Func<bool>>(expression).Compile()(); 
} 

public static class Methods 
{ 
    public static void MapListToField<T>(List<T> genericList) 
    { 
     foreach (var element in genericList) 
     { 
      Console.Write("{0}, ", element.ToString()); 
     } 
     Console.Write("\n"); 
    } 
    public static bool CastToList<L, T>(L obj) 
    { 
     if (obj.GetType() == typeof(List<T>)) 
     { 
      Console.Write("List contains objects of Type: {0}\n", typeof(T).ToString()); 
      List<T> genericList = obj as List<T>; 
      MapListToField(genericList); 
      return true; 
     } 
     else 
     { 
      Console.Write("Not list, Type is: {0}\n", typeof(L).ToString()); 
      return false; 
     } 
    } 
} 

Ergebnis:

List contains objects of Type: System.String 
a, b, c, 
List contains objects of Type: System.Int32 
1, 2, 3, 
Not list, Type is: System.String 
+0

Danke Eric. Ich versuchte das, aber sobald ich den Elementtyp hatte, konnte ich nicht in eine Liste dieses Typs umwandeln. Ich habe so etwas versucht: var myCastedList = (Liste ) genericData; Es mochte nicht den ElementType, den ich in List platziert hatte, und beschwerte mich darüber, dass es eine Variable war, die ich als Typ – rvb01

+0

verwenden wollte. Sie können Ausdrücke verwenden, sie haben eine große Flexibilität für generische Typen. Sie können Expression.Convert verwenden, nachdem Sie die Typen identifiziert haben, die in den gewünschten Typ und die Ausführung umgewandelt werden sollen. https://msdn.microsoft.com/en-us/library/mt654265.aspx Ich könnte versuchen, ein detailliertes Beispiel zu schreiben. – Eric

+0

Kennen Sie den Typ der Objekte der Liste, die Sie erwarten? – Eric

-1

Ohne eine gute Minimal, Complete, and Verifiable code example und mehr Einzelheiten über Ihr Szenario, ist es unmöglich, sicher zu wissen, was der beste Ansatz wäre hier. Das sagte & hellip;

Wenn Sie als Erstes überprüfen, ob das Objekt eine Liste ist, und es dann an eine andere Methode übergeben, die auf einer Liste operiert, warum nicht einfach zwei Überladungen für Ihre Methode erstellen? Z.B .:

public void MapData<T>(T genericData) 
{ 
    // do stuff with non-list data 
} 

public void MapData<T>(List<T> genericList) 
{ 
    MapListToField(genericList); 
} 

Wenn Code, den Sie für beide Arten ausführen wollen, ist, dass auf eine Hilfsmethode bewegen, dass beide Überlastungen von MapData<T>() aufrufen können.

Unabhängig davon, wie Sie sich diesem nähern, ist Ihr derzeitiger Mechanismus zum Überprüfen auf den List<T> Typ zu zerbrechlich und IMHO unwiederbringlich fehlerhaft. Einige Ideen zu besseren Möglichkeiten finden Sie unter How do I check if a given value is a generic list?.

Verwandte Themen