如何遍历泛型类型的列表

时间:2013-11-06 11:42:33

标签: c#

我需要循环遍历编译时未知类型的列表。怎么做?以下代码在运行时失败,不允许转换:

    Type objType = dataObject.GetType();
    List<string> strList = new List<string>();

    foreach (PropertyInfo prop in objType.GetProperties())
    {
        var val = prop.GetValue(dataObject);

        if (prop.PropertyType.Name.StartsWith("List"))   // Is there a better way?
        {
            foreach (object lval in (List<object>) val)  // Runtime failure (conversion not allowed)
            {
                strList.Add(lval.ToString());
            }
        }
        ...

4 个答案:

答案 0 :(得分:5)

如果您不知道类型,那么:泛型可能不是最佳选择:

IList list = val as IList; // note: non-generic; you could also
                           // use IEnumerable, but that has some
                           // edge-cases; IList is more predictable
if(list != null)
{
    foreach(object obj in list)
    {
        strList.Add(obj.ToString());
    }
}

答案 1 :(得分:1)

只是想在已经说过的内容中添加一些内容:

您的逻辑存在缺陷,因为List<int>(例如)不是List<object>的子类。 List<T>在其类型参数中不是协变的。

如果是,那么这样做是合法的:

List<object> listOfObjects = new List<int>();
listOfObjects.Add("a string");

阅读本文以了解有关C#中协方差/逆变的更多信息:

http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx

答案 2 :(得分:0)

foreach (var propInfo in foobar.GetType().GetProperties())
{
    var val = propInfo.GetValue(foobar, null);

    if (typeof(IEnumerable).IsAssignableFrom(propInfo.PropertyType))
    {
        var collectionItems = (IEnumerable)val;
        if (collectionItems != null)
        {
            foreach (object lval in collectionItems)
            {
                Console.WriteLine(lval);
            }
        }
    }
}

答案 3 :(得分:0)

也许会更容易

 foreach (PropertyInfo prop in objType.GetProperties())
        {
            var val = prop.GetValue(x,null);

            if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType) && prop.PropertyType.IsGenericType)   // Is there a better way?
            {
                dynamic dd = val;
                foreach (object lval in dd)  
                {
                    strList.Add(lval.ToString());
                }
            }