背景
在.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(...)
。
答案 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.
}
}
}