none
PropertyDescriptor.Attributes doesn't return all attributes

    Question

  • Hi,

    I've stumbled over a strange behavior of PropertyDescriptor.Attributes. I've decorated some of my properties with custom attributes like that:

    [MyAttribute(Information about visibility in a special case)]
    [MyAttribute(Information visibility in another case)]
    public string CreatedBy { ... }

    Using plain reflection (PropertyInfo) I get both attributes, but when I use PropertyDescriptor retrieved from a TypeDescriptor, I only get one of the attributes. And the funny thing is, for some properties I get the first one, for other properties I get the second one (and it changes if I remove one of the attributes). I already checked if maybe Equals and GetHashCode need to be overriden in the attribute implementation, but I didn't get any hits on a breakpoint there.

    Did anybody run into the same problem ? I tend to see that as a bug ... ?!

    Any help appreciated,
    Wolfgang
    Tuesday, July 14, 2009 8:40 AM

Answers

  • I repro.  This appears to be by design, there's code in the MemberDescriptor base class that filters attributes (FilterAttributesIfNeeded).  The filtering removes duplicate attributes.  Which one you'll get is unpredictable because of the way reflection metadata is cached.  Attribute types that have AllowMultiple = true are thus not supported.

    Not sure why this was done, there is no workaround for this behavior that I see if you use PropertyDescriptor.  I'd guess this might have something to do with avoiding complications in the designer. 

    Using PropertyInfo is an alternative.  Or use a distinct attribute type.

    Hans Passant.
    • Marked as answer by Wollinet Tuesday, July 14, 2009 12:55 PM
    Tuesday, July 14, 2009 12:27 PM

All replies

  • I repro.  This appears to be by design, there's code in the MemberDescriptor base class that filters attributes (FilterAttributesIfNeeded).  The filtering removes duplicate attributes.  Which one you'll get is unpredictable because of the way reflection metadata is cached.  Attribute types that have AllowMultiple = true are thus not supported.

    Not sure why this was done, there is no workaround for this behavior that I see if you use PropertyDescriptor.  I'd guess this might have something to do with avoiding complications in the designer. 

    Using PropertyInfo is an alternative.  Or use a distinct attribute type.

    Hans Passant.
    • Marked as answer by Wollinet Tuesday, July 14, 2009 12:55 PM
    Tuesday, July 14, 2009 12:27 PM
  • Thx for the fast response. I was afraid of something like that. In the meantime a found a workaround which is working as long as the component type returned by the descriptor really has the property:
    propertyDesc.ComponentType.GetProperty( propertyDesc.Name ).GetCustomAttributes( typeof( ... ), true )

     

    Luckily this solves the problem in my case, but it's not really "nice".

    Thx again !

    --
    Wolfgang

    Tuesday, July 14, 2009 12:55 PM
  • The solution to this is to override TypeId on the custom attribute class.  TypeId is what the framework uses to determine whether occurrences of the same attribute type are "duplicates"; if you want to be able to apply an attribute multiple times, just make sure that TypeId returns different values for each attribute instance.
    Mindscape WPF controls: http://www.mindscape.co.nz/products/
    Wednesday, September 02, 2009 4:00 AM
  • Cool, I'll gonna try. Thx for the info.

    --
    Wolfgang
    Wednesday, September 02, 2009 6:05 AM