IEnumerable <t>和反射</t>

时间:2010-05-10 11:15:56

标签: c# .net reflection .net-2.0 ienumerable

背景

在.NET 2.0中工作在这里,反映一般的列表。我最初使用t.IsAssignableFrom(typeof(IEnumerable))来检测我正在遍历的属性是否支持IEnumerable接口。 (因此我可以安全地将物体投射到它上面)

但是,当对象为True时,此代码未评估BindingList<T>

下一步

我尝试使用t.IsSubclassOf(typeof(IEnumerable))并且也没有任何运气。

代码

    /// <summary>
    /// Reflects an enumerable (not a list, bad name should be fixed later maybe?)
    /// </summary>
    /// <param name="o">The Object the property resides on.</param>
    /// <param name="p">The Property We're reflecting on</param>
    /// <param name="rla">The Attribute tagged to this property</param>
    public void ReflectList(object o, PropertyInfo p, ReflectedListAttribute rla)
    {
        Type t = p.PropertyType;
        //if (t.IsAssignableFrom(typeof(IEnumerable)))
        if (t.IsSubclassOf(typeof(IEnumerable)))
        {
            IEnumerable e = p.GetValue(o, null) as IEnumerable;

            int count = 0;
            if (e != null)
            {
                foreach (object lo in e)
                {
                    if (count >= rla.MaxRows)
                        break;

                    ReflectObject(lo, count);

                    count++;
                }
            }
        }
    }

意图

我想基本上标记我希望用ReflectedListAttribute反映的列表,并在具有它的属性上调用此函数。 (已经工作)

一旦进入这个函数,给定属性所在的对象,并且PropertyInfo相关,获取属性的值,将其转换为IEnumerable(假设它是可能的),然后遍历每个子节点并调用具有计数变量的孩子的ReflectObject(...)

4 个答案:

答案 0 :(得分:11)

执行as IEnumerable并且变量不为null时,您知道它确实实现了IEnumerable接口。

您不需要代码:

Type t = p.PropertyType;
//if (t.IsAssignableFrom(typeof(IEnumerable)))
if (t.IsSubclassOf(typeof(IEnumerable)))
{

这就足够了:

public void ReflectList(object o, PropertyInfo p, ReflectedListAttribute rla)
{
    IEnumerable e = p.GetValue(o, null) as IEnumerable;

    int count = 0;
    if (e != null)
    {
        foreach (object lo in e)
        {
            if (count >= rla.MaxRows)
                break;
            ReflectObject(lo, count);
            count++;
        }
    }
}

答案 1 :(得分:4)

来自MSDN

  

无法使用IsSubclassOf方法   确定是否有接口   派生自另一个接口,或   一个类是否实现了   interface为此目的使用GetInterface方法

你的IsAssignableFrom实现也是错误的,你应该像这样使用它:

typeof(IEnumerable).IsAssignableFrom(t)

如果IEnumerable由t ..实现,则应该返回true。

答案 2 :(得分:3)

为什么你要使用if语句?

你已经做了var e = ... as IEnumerable,之后只检查是否为空。

还不够吗?

答案 3 :(得分:1)

这些工作。 :)

List已展开Collection。因此,测试对他们来说是不同的。 Dictionary有两个内部容器。因此对此进行了一次测试。

public static bool IsList(object obj)
{
    System.Collections.IList list = obj as System.Collections.IList;
    return list != null;
}

public static bool IsCollection(object obj)
{
    System.Collections.ICollection coll = obj as System.Collections.ICollection;
    return coll != null;
}

public static bool IsDictionary(object obj)
{
    System.Collections.IDictionary dictionary = obj as System.Collections.IDictionary;
    return dictionary != null;
}



用法示例 -

if (IsDictionary(fieldObject)) //key-value type collection?
{
    System.Collections.IDictionary dictionary = fieldObject as System.Collections.IDictionary;
    foreach (object _ob in dictionary.Values)
    {
        //do work
    }
    // dictionary.Clear();
}
else //normal collection
{
    if (IsCollection(fieldObject))
    {
        System.Collections.ICollection coll = fieldObject as System.Collections.ICollection;
        foreach (object _ob in coll)
        {
            //do work
        }

        if (IsList(fieldObject))
        {
            //System.Collections.IList list = fieldObject as System.Collections.IList;
            //list.Clear(); // <--- List's function, not Collection's.
        }
    }
}