This project has moved. For the latest updates, please go here.

Getting properties of class including inherited properties but without hidden properties of parent class

Aug 29, 2012 at 2:48 PM

I try to access properties of a class. The accessed properties can either be declared in the base type, declared virtual in the base type and overriden in the concrete class, or declared non-virtual in the base type and shadowed in the concrete class.

Considering I have the following classes:

 

public class foo {

  public virtual object Property1 { get; set; }

  public virtual object Property2 { get; set; }

  public object Property3 { get; set; }

  public object Property4 { get; set; }

}

public class bar: foo {

  public override object Property1 { get; set; }

  public new object Property3 { get; set; }

}

 

 

I need the following results:

- Querying property "Property1" on bar returns bar.Property1

- Querying property "Property2" on bar returns foo.Property2

- Querying property "Property3" on bar returns bar.Property3

- Querying property "Property4" on bar returns foo.Property4

Property("MyPropertyName", Flags.ExcludeBackingMembers) seems to not exclude hidden properties. Resulting in an exception if querying "bar" for "Property3".

Is there an easy way to access such properties (without looping through all properties)?

 

 

 

 

 

 

 

 

Coordinator
Aug 29, 2012 at 6:48 PM
Edited Aug 29, 2012 at 6:49 PM

If I understand you correctly, you would like an option to execute code like this:

typeof(bar).Properties( Flags.InstanceAnyVisibility | Flags.ExcludeBackingMembers )

and have it return a list of 4 properties (as outlined in your post) - but it currently returns 5 members.

The ExcludeBackingMembers flag (documentation here) does not currently exclude hidden/shadowed members. I suppose it would be useful with a flag to do so (e.g. Flags.ExcludeHiddenMembers) that you could pass in, but this is not currently available.

However, Fasterflect returns properties from subclasses before any from base classes, so you could use this workaround:

public class PropertyNameComparer : IEqualityComparer<PropertyInfo>
{
    public bool Equals(PropertyInfo p1, PropertyInfo p2)
    {
        return p1.Name.Equals( p2.Name );
    }

    public int GetHashCode(PropertyInfo p)
    {
        return p.Name.GetHashCode();
    }
}

var props = typeof(bar).Properties( Flags.InstanceAnyVisibility | Flags.ExcludeBackingMembers ).Distinct( new PropertyNameComparer() );

This should filter out any (subsequent) properties with the same name, thus yielding the expected four properties.

Aug 29, 2012 at 7:18 PM

Yes, something like Flags.ExcludeHiddenMembers is exactly what I was looking for. I already use a workaround similar to yours (using FirstOrDefault instead of Distinct)

Thanks

Pascal

Coordinator
Aug 29, 2012 at 11:09 PM

I have a couple of other items that I want to fix and will put this on the list as well - thanks for the suggestion :)

Coordinator
Sep 14, 2012 at 4:56 AM
Edited Sep 14, 2012 at 4:58 AM

Fasterflect 2.1.1 has been released and now contains an ExcludeHiddenMembers flag.

It turned out to be overly complex to attempt to filter members based on the presence of the "new" modifier, as the information provided by the reflection subsystem is a bit limited. As such, it has been implemented using simple name matching, albeit with support for not excluding overloaded methods (i.e. only one method per parameter signature is allowed).