我有以下类定义:
[ActionsClass[typeof(MyActions)]
public class NkProject
{
int ProjectId;
IList<NkItem> Items;
NkItem SingleItem;
}
该类主要仅包含字段,class属性指出哪个类负责&#34;处理&#34;这个类是更大框架的一部分。
使用反射,我解析此文件以生成一些元数据,并且我想知道&#34;项目&#34;是List类型(或作为列表的任何类型的集合),但到目前为止我尝试过的所有内容都失败了。我正在遍历一组FieldInfo[]
个对象。
检查IEnumerable
:
if(field.FieldType.GetInterface("IEnumerable") != null)
这也检测到字符串为IEnumerables,这是不正确的。如果字符串无法通过此检查并且在某种意义上被视为原语(我else
的{{1}}),我更喜欢。
上面更改为:if
,但也失败了。
更改为:if(field is ICollection)
,但仍无法正确检测到。
有没有办法只查看变量引用的类型,以确定if(field is IList && field.GetType().IsGenericType)
是否为List类型并且Items
的并行检查失败?我猜测上面的#2和#3失败了,因为string Items
不是一个对象,因此没有附加任何继承信息。我错了,但我认为发生了什么。 Items
将类型返回为IList`1。不知道怎么解决这个问题。
EDIT / UPDATE :如果上述检查失败,并且字符串经过,则输出元格格式不正确。因为,如果它是项目的集合/列表,我需要为它们获取更多元数据(通过适当设置的属性)。仅当变量属于List / Collection类型时才执行此步骤,但如果它是单个引用或基元,则不执行此步骤。
反思代码:
field.GetType().Name
答案 0 :(得分:3)
您可以使用通用类型信息来检查它是否是List
if(field.FieldType.IsGenericType
&& field.FieldType.GetGenericTypeDefinition() == typeof(List<>))
目前我的代码库中有以下功能用于此类情况。
public static bool Closes(this Type type, Type openType)
{
if (type == null)
return false;
if (type.IsGenericType && type.GetGenericTypeDefinition() == openType) return true;
foreach (var @interface in type.GetInterfaces())
{
if (@interface.Closes(openType)) return true;
}
return type.BaseType.Closes(openType);
}
这样你就可以打电话了
field.FieldType.Closes(typeof(List<>)
答案 1 :(得分:1)
您可以尝试以下方法:
public bool IsGenericList(Type type)
{
if (type == null)
return false;
if (!type.IsGenericType)
return false;
var genericArguments = type.GetGenericArguments();
if (genericArguments.Length != 1)
return false;
var listType = typeof(IList<>).MakeGenericType(genericArguments);
return listType.IsAssignableFrom(type);
}