How can I use reflection to determine what attribute is applied at each level of inheritance?
var AttributeArray = 开发者_Go百科gUser.GetType().GetCustomAttributes(true);
Call GetCustomAttributes on each type in the inheritance chain and pass false for the inherited
parameter.
Type t = gUser.GetType();
while (t != null && t != typeof(object)) {
var attributes = t.GetCustomAttributes(false);
// do something with this level of attributes
t = t.BaseType;
}
If you want to be able to also get custom attributes declared on the interfaces that the type also implements in addition to those on its inheritance chain here's a linq-ish way to do it.
First, get the inheritance chain:
// recursive lambda functions must initially be
// assigned null to allow recursive calls
Func<Type, IEnumerable<Type>> getInheritanceChain = null;
getInheritanceChain = t =>
{
IEnumerable<Type> ts = new [] { t, };
var bt = t.BaseType;
if (bt != null)
{
ts = ts.Concat(getInheritanceChain(bt));
}
return ts;
};
This function is similar to Josh's answer but returns an IEnumerable<Type>
that you can use with any linq expression.
Second, concatenate the inheritance chain types with the interface types implemented by the type in question. This gives the complete list of types that the original object can be legally cast to.
Finally build a dictionary with type as the key and calls to .GetCustomAttributes(false)
to create values of type IEnumerable<Attribute>
:
Func<Type, IDictionary<Type, Attribute[]>> getCustomAttributesByType =
t => getInheritanceChain(t)
.Concat(t.GetInterfaces())
.ToDictionary(
x => x,
x => x.GetCustomAttributes(false)
.Cast<Attribute>()
.ToArray());
The end result is a simple call to build an easy to use dictionary.
IDictionary<Type, Attribute[]> lookup =
getCustomAttributesByType(gUser.GetType());
If it's run against System.String
the dictionary contains these values:
System.String
-> System.Reflection.DefaultMemberAttribute
-> System.Runtime.InteropServices.ComVisibleAttribute
-> System.SerializableAttribute
System.Object
-> System.Runtime.InteropServices.ComVisibleAttribute
-> System.Runtime.InteropServices.ClassInterfaceAttribute
-> System.SerializableAttribute
System.IComparable
-> System.Runtime.InteropServices.ComVisibleAttribute
System.ICloneable
-> System.Runtime.InteropServices.ComVisibleAttribute
System.IConvertible
-> System.Runtime.InteropServices.ComVisibleAttribute
-> System.CLSCompliantAttribute
System.IComparable<System.String>
System.Collections.Generic.IEnumerable<System.Char>
-> System.Runtime.CompilerServices.TypeDependencyAttribute
System.Collections.IEnumerable
-> System.Runtime.InteropServices.ComVisibleAttribute
-> System.Runtime.InteropServices.GuidAttribute
System.IEquatable<System.String>
精彩评论