When using custom attributes in .Net, one of the most common tasks is to query a member for any custom attributes that are applied. The MemberInfo class has a GetCustomAttributes method for just this purpose.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
This is fairly straightforward reflection code that loops through all of the public properties on ClassWithAttribute
and returns the names of any that have the ExampleAttribute
applied. In the example shown, on line 29 the properties
variable will be a list containing the words “Name” and “Age”.
But what happens if we use a class derived from ClassWithAttribute
?
1 2 3 4 5 6 7 8 |
|
Perhaps surprisingly, the properties
variable on line 7 contains the single word “Age”. This surprised me since I’m supplying true
as the second parameter to GetCustomAttributes()
on line 21 of the first example. When the second parameter is true, the member’s inheritance chain should be searched for attributes. So why didn’t it find the ExampleAttribute
declared in ClassWithAttribute
? The answer is in the documentation, although I missed it the first few times I read it (emphasis mine):
inherit: true to search this member’s inheritance chain to find the attributes; otherwise, false. This parameter is ignored for properties and events; see Remarks.
The second parameter to GetCustomAttributes()
is ignored if the method is being called on a property or an event (we have a property in this case). Luckily the “Remarks” section of the documentation has a solution (emphasis mine):
This method ignores the inherit parameter for properties and events. To search the inheritance chain for attributes on properties and events, use the appropriate overloads of the Attribute.GetCustomAttributes method.
So in this case we can simply replace line 21 in AttributeChecker.PropertiesWithAttribute()
with the following:
1
|
|
Now running the code for DerivedClassWithAttribute
will correctly return both “Name” and “Age”. A simple change, but something that tripped me up for a while none the less.