Как получить свойства для наследуемого класса по этому условию
У меня есть Person
класс, который наследует PersonBase
и этот второй класс наследует EntityBase
:
public class Person : PersonBase
{
virtual public string FirstName { get; set; }
virtual public string LastName { get; set; }
}
А также
public class PersonBase : EntityBase
{
virtual public string GroupName { get; set; }
}
А также
public class EntityBase : IEntity
{
public virtual long Id { get; protected set; }
public virtual string Error { get; protected set; }
}
Мне нужно получить список свойств Person
а также PersonBase
классы:
var entity = preUpdateEvent.Entity;
foreach (var item in entity.GetType().GetProperties()) //only FirstName & LastName & GroupName
{
if (item.PropertyType == typeof(String))
item.SetValue(entity, "XXXXX" ,null);
}
Сейчас GetProperties()
это включает в себя: FirstName, LastName, GroupName, Id, Error
но мне нужны только собственные свойства Person, а именно: FirstName, LastName, GroupName
Конечно, я использовал приведенный ниже код, но он не подходит для меня, потому что он включает только свойства Person
учебный класс.
var properties = typeof(Person).GetProperties(BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.DeclaredOnly);
Как я могу получить свойства, которые определены только на Person
а также PersonBase
классы?
4 ответа
Вот общее решение вашей проблемы в форме метода расширения:
public static PropertyInfo[] GetPropertiesUpTo<T>(this Type type, BindingFlags flags = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance)
{
return type.GetProperties(flags)
.Where(p => p.DeclaringType == typeof(T) || p.DeclaringType.IsSubclassOf(typeof(T)))
.ToArray();
}
Вы можете использовать это так:
var properties = typeof(Person).GetPropertiesUpTo<PersonBase>();
var properties = typeof(Person).GetProperties()
.Where(p => p.DeclaringType == typeof(PersonBase) || p.DeclaringType == typeof(Person));
Вы должны будете найти это рекурсивно, пройдя через typeof(Person).BaseType
который вернется PersonBase
,
Вы не можете сказать GetProperties()
"сколько" классов для получения свойств - он либо получает свойства для текущего класса и всех классов, которые он расширяет / наследует, либо (используя BindingFlags.DeclaredOnly
) он может получить только свойства текущего класса.
Вы можете использовать два вызова для получения свойств:
var properties = typeof(Person).GetProperties(BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.DeclaredOnly);
var parentProperties = typeof(PersonBase).GetProperties(BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.DeclaredOnly);
Или фильтр по полному списку возвращается без использования BindingFlags.DeclaredOnly
с использованием каждого свойства DeclaringType
значение. Это может быть сделано с linq
как показал Ли, или просматривая полный список свойств и используя if-statement
:
List<PropertyInfo> properties = new List<PropertyInfo>();
foreach (PropertyInfo pi in typeof(Person).GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
if ((pi.DeclaringType == typeof(PersonBase)) || (pi.DeclaringType == typeof(Person))) {
properties.Add(pi);
}
}