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));
}