使用反射循环IEnumerable <>中的值

Tre*_*rev 27 c# generics reflection

给定一个可能包含一个对象的对象IEnumerable<T>,我如何检查一个IEnumerable<T>属性是否存在,如果存在,则IEnumerable<T>使用反射遍历所有值,对于任何T

Phi*_*idt 26

foreach (var property in yourObject.GetType().GetProperties())
{
    if (property.PropertyType.GetInterfaces().Contains(typeof(IEnumerable)))
    {
        foreach (var item in (IEnumerable)property.GetValue(yourObject, null))
        {
             //do stuff
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意像`String`这样的类实现了IEnumerable,所以你可能并不总是得到你期望的结果(除非你想要一个char数组......) (2认同)
  • @sehe `var item in (IEnumerable&lt;&gt;)propertyInfo.GetValue(model)` 给我“意外使用未绑定的通用名称”,而 `var item in (IEnumerable)propertyInfo.GetValue(model)` 给我“使用通用名称”类型 'IEnumerable&lt;T&gt; 需要 1 个类型参数'"...不确定我应该实现什么? (2认同)
  • 如果有人在我上面的评论中遇到错误,您需要包含“System.Collections”,而不仅仅是像我一样的“System.Collections.Generic”:),然后您可以在 (IEnumerable)propertyInfo.GetValue 中使用“var item” (模型)` (2认同)

Voi*_*ain 7

好吧,你可以像Aghilas所说的那样测试它,一旦测试并确认为IEnumerable,你可以这样做:

public static bool IsEnumerable( object myProperty )
{
    if( typeof(IEnumerable).IsAssignableFrom(myProperty .GetType())
        || typeof(IEnumerable<>).IsAssignableFrom(myProperty .GetType()))
        return true;

    return false;
}

public static string Iterate( object myProperty )
{
    var ie = myProperty as IEnumerable;
    string s = string.Empty;
    if (ie != null)
    {
        bool first = true;
        foreach( var p in ie )
        {
            if( !first )
                s += ", ";
            s += p.ToString();
            first = false;
        }
    }
    return s;
}

foreach( var p in myObject.GetType().GetProperties() )
{
    var myProperty = p.GetValue( myObject );
    if( IsEnumerable( myProperty ) )
    {
        Iterate( myProperty );
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果只是低估了我的答案的人解释了为什么他/她这样做而不仅仅是downvote,那将是非常好的,否则它不会为讨论添加任何有价值的东西. (5认同)