如何在Reflection中迭代List

时间:2011-05-10 12:01:22

标签: c# reflection

我有一个名为Students的属性,类型为List<Student>

在反思中,我可以获得学生财产的价值。

现在的问题是如何迭代学生名单。

我需要检查StudentID [某个值]是否在该集合中。

var collection = studentPro.GetValue(studentObj,null);

//I need to iterate like this,

foreach(var item in collection)
{
     if(item.StudentID == 33)
         //Do stuff
}

请帮帮我。

5 个答案:

答案 0 :(得分:15)

您只需要施放

var collection = (List<Student>) studentPro.GetValue(studentObj,null);

返回给您并存储在var中的值的类型为object。因此,在尝试循环之前,首先需要将其强制转换为List<Student>

RANT

这就是为什么我个人不喜欢var,它隐藏了类型 - 除非在VS中将鼠标悬停在它上面。如果它是一个类型为object的声明,很明显我们无法迭代它。


更新

  

是的好。但铸造应该是   完成反思。在反思我们   不知道列表的类型。我们不   知道studentObj的实际类型

为了做到这一点,你可以转换为IEnumerable

var collection = (IEnumerable) studentPro.GetValue(studentObj,null);

答案 1 :(得分:2)

试试这个

IEnumerable<Student> collection = (IEnumerable<Student>)studentPro.GetValue(studentObj,null);

答案 2 :(得分:2)

其他人建议转换为List但我会假设这对你不起作用......如果你有权访问Student类,你就不会使用反射开始。因此,只需要转换为IEnumerable,然后在循环中,您将不得不再次使用反射来访问集合中每个项目所需的任何属性。

var collection = (IEnumerable)studentPro.GetValue(studentObj,null)

答案 3 :(得分:1)

你尝试的方式是正确的。您只需修复代码并转换GetValue的返回值:

var collection = (List<Student>)studentPro.GetValue(studentObj,null);

foreach(var item in collection)
{
     if(item.StudentID == 33)
         //Do stuff
}

答案 4 :(得分:0)

您可以使用以下内容从代理对象中创建POCO对象。请注意,我依赖于使用XMLIgnore属性来打破循环引用

static object DeepCopy(object obj, Type targetType)
    {
        if (obj != null)
        {
            Type t = obj.GetType();

            object objCopy = Activator.CreateInstance(targetType);

            Type copyType = targetType;

            var props =
                t.GetProperties();

                    //.Where(x => x.PropertyType.GetCustomAttributes(typeof(XmlIgnoreAttribute), false).Length == 0);
            foreach (var propertyInfo in props)
            {
                var targetProperty = copyType.GetProperties().Where(x => x.Name == propertyInfo.Name).First();

                if (targetProperty.GetCustomAttributes(typeof(XmlIgnoreAttribute), false).Length > 0)
                {
                    continue;
                }

                if (propertyInfo.PropertyType.IsClass)
                {
                    if (propertyInfo.PropertyType.GetInterface("IList", true)!=null)
                    {
                        var list = (IList)Activator.CreateInstance(targetProperty.PropertyType);

                        targetProperty.SetValue(objCopy,list);

                        var sourceList = propertyInfo.GetValue(obj) as IList;

                        foreach (var o in sourceList)
                        {
                            list.Add(DeepCopy(o, targetProperty.PropertyType.UnderlyingSystemType.GenericTypeArguments[0]));
                        }

                    }
                    else if (propertyInfo.PropertyType == typeof(string))
                    {
                        targetProperty.SetValue(objCopy, propertyInfo.GetValue(obj));
                    }
                    else
                    {
                        targetProperty.SetValue(objCopy, DeepCopy(propertyInfo.GetValue(obj), targetProperty.PropertyType));
                    }

                }
                else
                {
                    targetProperty.SetValue(objCopy,propertyInfo.GetValue(obj));
                }
            }

            return objCopy;

        }
        return null;
    }

    class MyDbContext:DbContext
{
    public MyDbContext():base(@"Server=(LocalDb)\v12.0;Trusted_Connection=True;")
    {

    }

    public DbSet<Table1> Table1s { get; set; }

    public DbSet<Table2> Table2s { get; set; }

}

public class Table1
{
    public int ID { get; set; }

    public string name { get; set; }

    virtual public List<Table2> Table2s { get; set; }
}


public class Table2
{
    public int ID { get; set; }

    public string Name { get; set; }
    [XmlIgnore]
    virtual public Table1 Table1 { get; set; }
}