Question

I have a Person class that inherits PersonBase and this second class inherits EntityBase:

public class Person : PersonBase
{        
   virtual public string FirstName { get; set; }
   virtual public string LastName { get; set; } 
}

And

public class PersonBase : EntityBase
{        
   virtual public string GroupName { get; set; }
}

And

public class EntityBase : IEntity
{    
   public virtual long Id { get; protected set; }
   public virtual string Error { get; protected set; }
}

I need to get list of properties of Person and PersonBase classes :

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

Now GetProperties() is include : FirstName, LastName, GroupName, Id, Error but I need only own Person properties namely : FirstName, LastName, GroupName

Of Course I has been used below code but it is not suitable for me because it is only include properties of Person class.

var properties = typeof(Person).GetProperties(BindingFlags.Public |
                                                  BindingFlags.Instance |
                                                  BindingFlags.DeclaredOnly);

How can I get the properties that are only defined on Person and PersonBase classes?

Was it helpful?

Solution

Here's a generic solution to your problem, in the form of an extension method:

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

You can use it like this:

var properties = typeof(Person).GetPropertiesUpTo<PersonBase>();

OTHER TIPS

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

You will have to recursively find it by going through typeof(Person).BaseType which will return PersonBase.

You cannot tell GetProperties() "how many" classes to get properties from - it either gets the properties for the current class and all classes it extends/inherits-from, or (by using BindingFlags.DeclaredOnly) it can get just the current class's properties.

You can use two calls to get the properties:

var properties = typeof(Person).GetProperties(BindingFlags.Public |
                                                  BindingFlags.Instance |
                                                  BindingFlags.DeclaredOnly);
var parentProperties = typeof(PersonBase).GetProperties(BindingFlags.Public |
                                                  BindingFlags.Instance |
                                                  BindingFlags.DeclaredOnly);

Or filter on the full list returned without using BindingFlags.DeclaredOnly, using each property's DeclaringType value. This can be done with linq as Lee has shown, or by looping through the full list of properties and using an 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);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top