2016-08-12 265 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

每埃里克的反应下面,我想分享一下我所做的尝试,也许有人可能会指出我的错误。编译器,说明我在尝试使用一个变量作为一个类型,这是我理解的意思,但是元素类型是一个类型,所以我不清楚如何解决:

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

回答

0

编辑:这是接近你在问什么?

代码:

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 =(List )genericData;它不喜欢我放在List中的ElementType,抱怨它是可变的,我试图用作类型 – 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>类型的机制太脆弱了,恕我直言,这个机制是无法挽回的。请参阅How do I check if a given value is a generic list?了解有关更好方式的一些想法。

相关问题