代码之家  ›  专栏  ›  技术社区  ›  Rodrigo Gama

使用C#反射访问IList中的项

  •  0
  • Rodrigo Gama  · 技术社区  · 16 年前

    我有一个具有Items属性的类,它是IList:

    class Stuff {
        IList<OtherStuff> Items;
    }
    

    我试过这个:

    object MyMethod(string s, object obj) {
        return obj.GetType().GetProperty(s).GetValue(obj,null);
    }
    

    正在使用“Items[0]”,但它不起作用。。。还尝试解析参数以仅访问对象的属性“Items”,然后访问索引(知道它是IList)。

    有什么想法吗?

    4 回复  |  直到 8 年前
        1
  •  1
  •   BlueCode    16 年前

    您可以访问该属性,然后将其转换为列表。

    T GetListItem<T>(object obj, string property, int index)
    {
        return (obj.GetType().GetProperty(property).GetValue(obj, null) as IList<T>)[index];
    }
    

    示例代码的工作示例:

    OtherStuff item = GetListItem<OtherStuff>(obj, "Items", 0);
    
        2
  •  1
  •   kbrimington    16 年前

    如果您想测试一个对象,看看它是否有一个数字索引器,而不考虑它是否是IList,然后通过反射调用索引器,您可以尝试这个方法。

    如果对象有索引器,则返回true,并填充 value 以及第0个索引的值。

    public static bool TryGetFirstIndexWithReflection(object o, out object value)
    {
        value = null;
    
        // find an indexer taking only an integer...
        var property = o.GetType().GetProperty("Item", new Type[] { typeof(int) });
    
        // if the property exists, retrieve the value...
        if (property != null)
        {
            value = property.GetValue(list, new object[] { 0 });
            return true;
        }
    
        return false;
    }
    

    请注意,这个示例没有尝试优雅地处理异常,例如 IndexOutOfRangeException . 如果你觉得相关的话,那就由你来补充。

        3
  •  0
  •   Peter Mortensen Pieter Jan Bonestroo    8 年前

    Items不是属性,所以我的方法不起作用。它应该是,所以我把它变成了一个财产,现在它工作顺利。

        4
  •  -1
  •   Peter Mortensen Pieter Jan Bonestroo    8 年前

    object GetFirstItemByReflection(object obj) {
        return obj.GetType().GetMethod("get_Item").Invoke(obj, new object[] { 0 } );
    }
    

    进行适当的检查。

    “get\u Item”是按索引访问集合中的项时使用的“generated”方法。

    当您获得它的MethodInfo时,您在集合中调用它,并将“0”参数传递给它,以获得第一个项。