如何通过此条件获取继承类的属性

时间:2012-08-18 12:29:02

标签: c# .net reflection bindingflags

我有一个继承Person的{​​{1}}类,第二个类继承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()但我只需要拥有Person属性,即:FirstName, LastName, GroupName, Id, Error

当然我已在代码下面使用但它不适合我  因为它只包含FirstName, LastName, GroupName类的属性。

Person

如何获取仅在var properties = typeof(Person).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); Person类中定义的属性?

4 个答案:

答案 0 :(得分:2)

以下是扩展方法形式的问题的通用解决方案:

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

答案 1 :(得分:1)

var properties = typeof(Person).GetProperties()
    .Where(p => p.DeclaringType == typeof(PersonBase) || p.DeclaringType == typeof(Person));

答案 2 :(得分:0)

您必须通过typeof(Person).BaseType递归PersonBase来递归找到它。

答案 3 :(得分:0)

你无法告诉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);

或使用每个属性的DeclaringType值过滤未使用BindingFlags.DeclaredOnly而返回的完整列表。这可以通过Lee展示的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);
    }
}