简体   繁体   English

如何最好地检查反射的List类型并对其成员进行迭代

[英]How to best check for List type on reflection and iterate over its members

I'm using reflection to get all properties of a specific object and iterate over them. 我正在使用反射来获取特定对象的所有属性并对其进行迭代。

I'm calling these properties props . 我称这些属性为props

When those are non-List objects, this all works fine. 当那些不是List对象时,一切正常。

I need a way to know when a prop I'm iterating over is a list (I saw there is a prop.PropertyType.IsArray for instance, but not one for list). 我需要一种方法来知道我要遍历的prop何时是列表(我看到有一个prop.PropertyType.IsArray例如,但列表没有一个)。

I saw here Determine if a property is a kind of array by reflection that they suggested to use: 我在这里看到了他们建议使用的反射确定属性是否是一种数组

property.PropertyType.GetInterface(typeof(IEnumerable<>).FullName) != null

But this is not good enough for me since string implements that as well. 但这对我来说还不够好,因为string也会实现这一点。

(Right now I'm checking that prop.Namespace contains "collection" in it, obviously looking for a better way). (现在,我正在检查prop.Namespace包含“集合”,显然是在寻找更好的方法)。

After I've done that, I have a working assumption that the List will be a List of a complex object. 完成此操作后,我有一个可行的假设,即List将是一个复杂对象的List。 (but could be one of several complex ojects so I don't know which) (但可能是几个复杂的对象之一,所以我不知道哪个)

The harder part is that I need to iterate over those objects and get their members as well, but have failed to do so. 更难的部分是我需要遍历那些对象并获取它们的成员,但是没有这样做。

So if I have List<TestObject> as my prop I need to have a foreach (TestObject testObj in prop) somehow (in concept). 因此,如果我将List<TestObject>作为prop我需要某种方式(在概念上)拥有一个foreach (TestObject testObj in prop) )。

Don't have a reasonable attempt to show here, since I haven't yet figured out a way to treat prop as a List of my complex object and iterate over it. 在这里没有进行合理的尝试,因为我还没有找到将prop当作我的复杂对象的List并对其进行迭代的方法。

EDIT: I've managed to get the value with prop.GetValue(reflectedObject) but I have to cast that to List<MyComplexObject> 编辑:我已经设法获得与prop.GetValue(reflectedObject)的值,但我不得不将其prop.GetValue(reflectedObject)List<MyComplexObject>

I think that working with the IEnumerable<> interface is actually the way forward. 我认为使用IEnumerable<>接口实际上是前进的道路。 Do you have some sort of a base type for your objects? 您的对象有某种基本类型吗? If yes, then you can work around the issue with string be looking for collections of objects that extend the base type. 如果是,则可以解决string问题,寻找扩展基本类型的对象集合。 If no, then you can treat strings as a special case before you check for the IEnumerable<> interface. 如果否,则可以在检查IEnumerable<>接口之前将字符串作为特殊情况处理。

I think looking into this code sample can help. 我认为研究此代码示例会有所帮助。

public class MyClass
{
    public string Name { get; set; }
    public int Id { get; set; }
    public List<int> Subordinates { get; set; }
}

Use MyClass: 使用MyClass:

var myClass = new MyClass
{
    Id = 1,
    Name = "My Name",
    Subordinates = new List<int> { 2, 5, 8 }
};

var props = myClass.GetType().GetProperties();
foreach (var info in props)
{
    var type = info.PropertyType;

    if (type.IsGenericType && (type.GetGenericTypeDefinition() == typeof(List<>)))
    {
        foreach (var listitem in info.GetValue(myClass, null) as IEnumerable)
        {
            Console.WriteLine("Item: " + listitem.ToString());
        }

        continue;
    }
    Console.WriteLine(info.GetValue(myClass, null));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM