C#类型的空列表

时间:2014-01-17 21:16:44

标签: c# .net list reflection types

我可以获得一种非空列表:

private Type GetListType(IEnumerable list)
{
  return list.GetType().GetGenericArguments()[0];
}

我如何获得一种空列表?

private Type GetListType(IEnumerable list)
{
...
}

3 个答案:

答案 0 :(得分:5)

您的代码也适用于空列表。 [0]GetGenericArguments调用返回的类型参数数组的索引器,而不是列表的内容。

答案 1 :(得分:4)

您所使用的代码,例如在

GetListType(new List<string>()); // typeof(string)

如果运行时类型没有泛型参数,则无效,例如

public class MyList : List<SomeObject> { }
GetListType(new MyList()); // there is no 0'th generic argument!

或者它可能无法返回您期望的内容:

GetListType(new Dictionary<string, int>()); // typeof(string)
// even though it ought to be KeyValuePair<string, int>

也许你应该使用它:

private Type GetListType<T>(IEnumerable<T> list)
{
  return typeof(T);
}

最大的缺点是你的类型必须实现IEnumerable<T>,而不仅仅是IEnumerable(但是如果你想从空列表中获得一个有用的类型,它必须这样做,或者以其他方式宣布其类型。

答案 2 :(得分:0)

正如其他人指出的那样,您拥有的代码可以正常使用空集合。但它只有在集合类型直接包含泛型变量时才有效。它不适用于具体的收藏品。例如

class IntList : List<int> { } 

GetListType(new List<int>()) // Works
GetListType(new IntList())   // Fails

类型IntList没有通用参数,因此索引操作[0]将失败。

要进行更通用的实现,您应该选择要查询泛型参数的特定接口或类类型。我建议IEnumerable<T>

static Type GetListType(IEnumerable enumerable)
{
    var type = enumerable.GetType();
    var enumerableType = type
        .GetInterfaces()
        .Where(x => x.GetGenericTypeDefinition() == typeof(IEnumerable<>))
        .First();
    return enumerableType.GetGenericArguments()[0];
}