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

C# 通过反射确定属性是否是一种数组,c#,reflection,C#,Reflection,如何确定属性是否为数组类型 例如: public bool IsPropertyAnArray(PropertyInfo property) { // return true if type is IList<T>, IEnumerable<T>, ObservableCollection<T>, etc... } public bool IsPropertyAnArray(PropertyInfo property) { //如果类型为IList、

如何确定属性是否为数组类型

例如:

public bool IsPropertyAnArray(PropertyInfo property)
{
    // return true if type is IList<T>, IEnumerable<T>, ObservableCollection<T>, etc...
}
public bool IsPropertyAnArray(PropertyInfo property)
{
//如果类型为IList、IEnumerable、ObservableCollection等,则返回true。。。
}

如果您想知道该属性是否为数组,实际上非常简单:

property.PropertyType.IsArray;
编辑

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

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

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

对于前者,只需选中
property.PropertyType.IsArray

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

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

例如,如果要检查泛型
IEnumerable
,可以使用以下命令:

public bool ispropertyCollection(PropertyInfo属性)
{ 
返回property.PropertyType.GetInterface(typeof(IEnumerable.FullName)!=null;
} 
数组还实现IEnumerable,因此它们也将从该方法返回
true

公共静态bool是GenericEnumerable(类型)
    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;
    }
{ 返回类型.IsGenericType&& 键入.GetInterfaces().Any( ti=>(ti==typeof(IEnumerable)| ti.Name==“IEnumerable”); } 公共静态布尔可数(类型) { 返回IsGenericEnumerable(type)| | type.IsArray; }
对我来说,以下内容不起作用

return property.PropertyType.GetInterface(typeof(ICollection<>).FullName) != null;
返回property.PropertyType.GetInterface(typeof(ICollection.FullName)!=无效的
下面的代码正在运行

typeof(ICollection<>).IsAssignableFrom(property.PropertyType.GetGenericTypeDefinition())
typeof(ICollection).IsAssignableFrom(property.PropertyType.GetGenericTypeDefinition())
这是检查
ICollection
ICollection

var property=请求为PropertyInfo;
property.PropertyType.IsGenericType&(typeof(ICollection).IsAssignableFrom(property.PropertyType.GetGenericTypeDefinition())&&typeof()。IsAssignableFrom(property.PropertyType.GenericTypeArguments[0])

排除
String
类,因为它实现了
IEnumerable
,因此符合集合的条件


你的意思是,如果财产是一个集合?与您的评论匹配的内容不是数组。您可能是指
IEnumerable
而不是
IEnumerator
?@Ben:数组符合他的条件(IList和IEnumerable),但并非所有符合他的条件的内容都是数组。:)我不确定这是否是OP真正想要的(但我承认命名有点误导)。实现IList的自定义类型将从此属性返回false。事实上,我最初误解了这个问题。我编辑了我的答案以包含任何内容IEnumerable@Falanwe:
issubclasssof
不适用于接口,只适用于基类。@Falanwe:我看不懂法语,但英语版本说“issubclasssof方法不能用于确定接口是否派生自另一个接口,或者类是否实现了接口”(强调我的)。@Sven:你说得对,我读文档太快了。我编辑了我的回答。这个实现将错过“旧式收藏”,继承自.Net 1,它实现了IEnumerable,但不是通用版本的IEnumerable。它们的使用越来越少,但一些API需要它们,这真是一个难题。@Falanwe:然后使用我提到的第一种方法,它会检查非通用的IEnumerable。这真的取决于他的要求,哪一种是最好的。我尝试你的方法如果属性为字符串且方法返回true,您知道为什么吗?@Melursus:
string
类实现了
IEnumerable
,因此它符合这些条件下的集合。您需要专门筛选它,或者检查更严格的接口(例如,
ICollection
IList
)。任何实现泛型
IEnumerable
的类型当然也将是非泛型
IEnumerable
。typeof(String)是缺少的检查
typeof(ICollection<>).IsAssignableFrom(property.PropertyType.GetGenericTypeDefinition())
var property = request as PropertyInfo;

property.PropertyType.IsGenericType && (typeof(ICollection<>).IsAssignableFrom(property.PropertyType.GetGenericTypeDefinition())) && typeof().IsAssignableFrom(property.PropertyType.GenericTypeArguments[0])
public bool IsPropertyACollection(this PropertyInfo property)
{
    return (!typeof(String).Equals(property.PropertyType) && 
        typeof(IEnumerable).IsAssignableFrom(property.PropertyType));
}