2016-08-12 3 views
1

У меня есть метод, который принимает в качестве аргумента общий тип T. Если T имеет список типов, я хотел бы передать его в список, где Y тип элемента, содержащегося в T. Я подозреваю, что я неправильно понимаю ограничения общих типов, но любая помощь будет оценена.Как создать общий тип T в список определенного типа

Пример:

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

мне нужно бросить genericData в список, так что я могу передать его другому методу с подписью:

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

UPDATE

Per ответ Эрика ниже, я хотел поделиться попыткой, которую я сделал, возможно, кто-то может указать на мою ошибку. Компилятор о том, что я пытаюсь использовать переменную как тип, который я понимаю смысл, но ElementType это тип, поэтому я не ясно, как исправить:

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

ответ

0

EDIT: Это близко на что вы спрашиваете?

Код:

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

Результат:

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

Спасибо Эрик. Я попытался это сделать, но как только у меня появился тип элемента, я не смог применить его к списку этого типа. Я попробовал что-то вроде этого: var myCastedList = (Список ) genericData; Ему не понравился элемент ElementType I, помещенный в List, жалуясь, что он был переменной, которую я пытался использовать в качестве типа – rvb01

+0

. Вы можете использовать выражения, они имеют большую гибкость для общих типов. Вы можете использовать Expression.Convert, как только вы определили типы, которые нужно применить к желаемому типу и выполнить. https://msdn.microsoft.com/en-us/library/mt654265.aspx Я мог бы попытаться написать подробный пример. – Eric

+0

Знаете ли вы тип объектов списка, который вы ожидаете получить? – Eric

-1

Без хорошего Minimal, Complete, and Verifiable code example, и более специфические о вашем сценарии, это невозможно знать наверняка, что лучший подход был бы здесь. Это сказало & hellip;

Если первое, что вы собираетесь сделать, это проверить, является ли объект списком, а затем просто передать его другому методу, который будет работать в списке, почему бы просто не сделать две перегрузки для вашего метода? Например .:

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

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

Если есть код, который вы хотите выполнить для обоих типов, что двигаться к вспомогательный метод, который можно назвать как перегруженные MapData<T>().

Независимо от того, как вы подходите к этому, ваш текущий механизм для проверки типа List<T> слишком хрупкий, и IMHO безвозвратно испорчен. См. How do I check if a given value is a generic list? для некоторых идей о лучших способах этого.