如何将通用类型T转换为特定类型的列表

时间:2016-08-12 02:54:35

标签: c# generics casting generic-list

我有一个方法,它将一个泛型T作为参数。如果T是Type List,我想把它转换为一个List,其中Y是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转换为List,以便我可以将它传递给另一个带签名的方法:

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

更新

根据Eric的回复,我想分享一下我做过的尝试,也许有人可以指出我的错误。编译器声明我正在尝试将变量用作Type,我理解其含义,但elementType是一个Type,所以我不清楚如何修复:

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:-1)

如果没有良好的Minimal, Complete, and Verifiable code example,以及有关您的方案的更多细节,我们无法确定最佳方法是什么。那说......

如果你要做的第一件事是检查对象是否是一个列表,然后将它传递给另一个将在列表上运行的方法,为什么不为你的方法做两次重载? E.g:

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?