我有以下课程:
public class BaseDataEntity
{
private List<string> _Changes = new List<string>();
public IEnumerable<string> GetChanges()
{
return _Changes;
}
public bool HasDataChanged
{
get { return (GetChanges().Count() > 0); }
}
public bool HasChildRecords
{
get { return (GetType().GetChildRecords().Count() > 0); }
}
}
public class ChildRecords : IList<T> where T : BaseDataEntity
{
}
还有一些辅助方法:
public static PropertyInfo[] GetChildRecords(this Type aType)
{
return aType.GetProperties().Where(pi => pi.IsChildRecords()).ToArray();
}
public static bool IsChildRecords(this PropertyInfo info)
{
return (info.GetCustomAttributes(typeof(ChildRecordsAttribute), false).Length > 0);
}
我想做的是使用反射实现一个名为HaveChildRecordsChanged的属性。我的问题是我将如何使用反射来检查任意深度的所有ChildRecords的HasDataChanged属性?
我尝试了类似的东西:
var isChanged = false;
foreach (var info in GetType().GetChildRecords())
{
var childRecordObject = info.GetValue(this, null);
var childRecords = childRecordObject as ChildRecords<BaseDataEntity>; //cannot unbox this, it evaluates as null
if (null != childRecords && childRecords.Any(x => x.HasDataChanged))
{
isChanged = true; //never hit
}
}
return isChanged;
最佳答案
ChildRecords<T>
是通用的,因此不能将ChildRecords<Company>
强制转换为ChildRecords<BaseDataEntity>
。
由于您已经过滤了标记为ChildRecordsAttribute
的属性,因此最简单的解决方案是将其强制转换为IEnumerable
并使用OfType<BaseDataEntity>()
var childRecords = childRecordObject as IEnumerable; // IList<T> will be IEnumerable
if (null != childRecords && childRecords.OfType<BaseDataEntity>().Any(x => x.HasDataChanged))
{
isChanged = true;
}