繁体   English   中英

IEnumerable <T> 和反思

[英]IEnumerable<T> and reflection

背景

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

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

下一个

我尝试使用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 ,获取属性的值,将其ReflectObject(...)转换为IEnumerable(假设可能),然后遍历每个子对象并在其上调用ReflectObject(...)具有count变量的孩子。

当您将其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++;
        }
    }
}

MSDN

IsSubclassOf方法不能用于确定一个接口是从另一个接口派生的,还是一个类是否实现一个接口,请使用GetInterface方法

同样,您的IsAssignableFrom的实现是错误的,您应该这样使用它:

typeof(IEnumerable).IsAssignableFrom(t)

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

为什么要全部使用if语句?

您已经将var e = ... as IEnumerable做过,之后只需检查是否不为null。

这还不够吗?

这些工作。 :)

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.
        }
    }
}

暂无
暂无

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

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