开发者

How can I correlate .NET reflection of attributes with each object?

开发者 https://www.devze.com 2023-02-03 18:46 出处:网络
How can I use reflection to determine what attribute is applied at each level of inheritance? var AttributeArray = 开发者_Go百科gUser.GetType().GetCustomAttributes(true);

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>
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号