【问题标题】:How to obtain a list of objects inside another object using reflection如何使用反射获取另一个对象内的对象列表
【发布时间】:2019-11-25 01:18:31
【问题描述】:

使用反射我可以获得所有数据类型的对象属性和值以及该对象内的对象。但是,如果该对象包含其他对象的列表,我将无法获取列表中的对象。该列表可以包含任何类型的对象。

private static void SaveObj(object obj) {
   foreach (var prop in obj.GetType().GetProperties()) {
       if (prop.PropertyType.Namespace == "Entities") { //It is an object
           object obL = prop.GetValue(obj, null);
           SaveObj(obj);
       }
       else if (prop.PropertyType.Name == "List`1") { //This is a list of objects
           object obP = prop.GetValue(obj); 
           //obP has the list of objects, I can see the list in debug mode.
           List<object> obL = (List<object>)prop.GetValue(obj, null);
           //This line returns an exception!!
       }
       else {
           columns += prop.Name.ToLower() + ", ";
           values[i] = prop.GetValue(obj, null).ToString();
       }
       ... // the code continues ...
   }
}     

返回的异常信息是: “无法转换 'System.Collections.Generic.List1[Entities.OrderItem]' to type 'System.Collections.Generic.List1[System.Object]' 类型的对象。”

有趣的是,我可以在 degug 模式下查看所有对象及其内容。在即时窗口中,我可以打印变量 obP 的内容以及列表中的所有对象,但是如何读取它们呢?

关于如何解决这个问题的任何想法?

【问题讨论】:

    标签: c# .net reflection


    【解决方案1】:

    您可以尝试将其转换为IEnumerable,然后使用.Cast&lt;object&gt;().ToList() 像这样:

    IEnumerable obL = prop.GetValue(obj, null) as IEnumerable;
    List<object> list = obL.Cast<object>().ToList();
    

    【讨论】:

    • 效果很好!感谢 Anton 的及时帮助。
    • @MarceloTropia 我很高兴它成功了。请点击复选标记考虑marking the answer as accepted。这向更广泛的社区表明您已经找到了解决方案,并为回答者和您自己提供了一些声誉。没有义务这样做。 :)
    【解决方案2】:

    如果List 实现了ICollection 接口,您可以执行以下操作,而不是尝试将返回值强制转换为List&lt;object&gt;,而是执行以下操作:

    ICollection collection = (prop.GetValue(obj, null) as ICollection);
    
    if (collection != null)
    {
        object[] array = new object[collection.Count];
    
        collection.CopyTo(array, 0);
    
        //if you need a list just create a new one and pass in the array: new List<object>(array);
    }
    

    顺便说一句,你的:

    if (prop.PropertyType.Namespace == "Entities")
    {
        object obL = prop.GetValue(obj, null);
        SaveObj(obj);
    }
    

    只是导致一个无限循环,这将导致 StackOverflow/OutOfMemory 异常,如果这是预期的行为,可能需要将其更改为 SaveObj(obL);

    【讨论】:

    • 感谢您的帮助文森特。事实上我没有尝试你的建议。我听从了安东的建议,效果很好。关于“循环”,是的,你是对的。我的意图是递归调用,正确的是“SaveObj(obL)”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2011-06-20
    • 1970-01-01
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多