如何在反射中迭代列表

发布于 2024-11-06 04:17:26 字数 371 浏览 1 评论 0原文

我有一个名为 Students 的属性,其类型为 List

经过反思我可以得到学生财产的价值。

现在的问题是如何迭代学生列表。

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

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

//I need to iterate like this,

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

请帮我。

I am having one property called Students which is of type List<Student>.

In reflection i can get the value of Students Property.

Now the problem is How to iterate the List of Students.

I need to check whether StudentID [ some value ] is in that collection.

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

//I need to iterate like this,

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

Please help me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

屋檐 2024-11-13 04:17:27

您只需强制转换它:

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

返回给您并存储在var中的值是object类型。因此,您需要先将其转换为 List,然后再尝试循环它。

RANT

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


更新

是的,这很好。但选角应该是
通过反思完成。反思中我们
不知道列表的类型。我们不
了解studentObj的实际类型

为此,您可以转换为IEnumerable

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

You just need to cast it:

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

The value returned to you and stored in var is of type object. So you need to cast it to List<Student> first, before trying looping through it.

RANT

That is why I personally do not like var, it hides the type - unless in VS you hover on it. If it was a declared with type object it was immediately obvious that we cannot iterate through it.


UPDATE

Yes its good. But casting should be
done with reflection. In reflection we
dont know the type of List. We dont
know the actual type of the studentObj

In order to do that, you can cast to IEnumerable:

var collection = (IEnumerable) studentPro.GetValue(studentObj,null);
二智少女猫性小仙女 2024-11-13 04:17:27

试试这个

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

Try this

IEnumerable<Student> collection = (IEnumerable<Student>)studentPro.GetValue(studentObj,null);
情未る 2024-11-13 04:17:27

其他人建议强制转换为 List,但我认为这对您不起作用...如果您有权访问 Student 类,那么您一开始就不会使用反射。因此,只需转换为 IEnumerable,然后在循环内,您必须再次使用反射来访问集合中每个项目的任何属性。

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

Others have suggested casting to List but I will assume that this won't work for you... if you had access to the Student class, you wouldn't be using reflection to begin with. So instead, just cast to IEnumerable and then inside your loop, you'll have to use reflection again to access whatever properties you want off of each item in the collection.

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

遥远的绿洲 2024-11-13 04:17:27

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

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

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

The way you tried is, is the right one. You just need to fix your code and cast the return value from GetValue:

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

foreach(var item in collection)
{
     if(item.StudentID == 33)
         //Do stuff
}
听你说爱我 2024-11-13 04:17:27

您可以使用如下所示的方法从代理对象中创建 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; }
}

You can have something like below to create a POCO object out of your proxy object. Please note that I am relying on use of XMLIgnore attribute to break circular references

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; }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文