通过反射确定属性是否是一种数组

时间:2012-02-24 16:58:31

标签: c# reflection

如何确定属性是否是一种数组。

示例:

public bool IsPropertyAnArray(PropertyInfo property)
{
    // return true if type is IList<T>, IEnumerable<T>, ObservableCollection<T>, etc...
}

5 个答案:

答案 0 :(得分:65)

您似乎在问两个不同的问题:类型是数组(例如string[])还是任何集合类型。

对于前者,只需检查property.PropertyType.IsArray

对于后者,您必须确定您希望类型符合的最低标准。例如,您可以使用IEnumerable检查非通用typeof(IEnumerable).IsAssignableFrom(property.PropertyType)。如果您知道T的实际类型,也可以将其用于通用接口,例如: typeof(IEnumerable<int>).IsAssignableFrom(property.PropertyType)

通过检查IEnumerable<T>是否不是property.PropertyType.GetInterface(typeof(IEnumerable<>).FullName),可以在不知道T值的情况下检查通用null或任何其他通用接口。请注意,我没有在该代码中为T指定任何类型。您可以对IList<T>或您感兴趣的任何其他类型执行相同操作。

例如,如果要检查通用IEnumerable<T>

,可以使用以下内容
public bool IsPropertyACollection(PropertyInfo property) 
{ 
    return property.PropertyType.GetInterface(typeof(IEnumerable<>).FullName) != null;
} 

Arrays也实现IEnumerable,因此它们也会从该方法返回true

答案 1 :(得分:19)

排除String类,因为它有资格作为集合,因为它实现了IEnumerable<char>

public bool IsPropertyACollection(this PropertyInfo property)
{
    return (!typeof(String).Equals(property.PropertyType) && 
        typeof(IEnumerable).IsAssignableFrom(property.PropertyType));
}

答案 2 :(得分:15)

如果你想知道属性是否是一个数组,那实际上很容易:

property.PropertyType.IsArray;

修改

如果你想知道它是否是一个实现IEnumerable的类型,就像所有“集合类型”一样,它也不是很复杂:

return property.PropertyType.GetInterface("IEnumerable") != null;

答案 3 :(得分:2)

    public static bool IsGenericEnumerable(Type type)
    {
        return type.IsGenericType && 
            type.GetInterfaces().Any(
            ti => (ti == typeof (IEnumerable<>) || ti.Name == "IEnumerable"));
    }

    public static bool IsEnumerable(Type type)
    {
        return IsGenericEnumerable(type) || type.IsArray;
    }

答案 4 :(得分:0)

对我来说,以下是行不通的,

return property.PropertyType.GetInterface(typeof(ICollection<>).FullName) != null;

以下工作正常,

typeof(ICollection<>).IsAssignableFrom(property.PropertyType.GetGenericTypeDefinition())

这是检查ICollection<IInterface>ICollection<BaseClassInTree>

的快捷方式
var property = request as PropertyInfo;

property.PropertyType.IsGenericType && (typeof(ICollection<>).IsAssignableFrom(property.PropertyType.GetGenericTypeDefinition())) && typeof().IsAssignableFrom(property.PropertyType.GenericTypeArguments[0])