onesiumus
onesiumus

Reputation: 319

How to get the type embedded within a custom attribute?

I have several classes that contain various attributes. Here is one example:

[XmlInclude(typeof(AFReader))]
[XmlInclude(typeof(SQLReader))]
[XmlInclude(typeof(MySQLReader))]
[Serializable]
[DataContract]
public class DataSource     
{
   ...                    
}

I need to be able to filter through these attributes and select the types whose BaseType is that in which it inherits (DataSource in this case).

So in the end I would like something like this:

List<Type> filteredAttributes = {typeof(AFReader), typeof(SQLReader), typeof(MySQLReader)};

//List<MemberInfo> .. would work as well

Things that I've tried:

    static private List<Type> AttributeFilter(IEnumerable<Attribute> attributes, Type baseType)
    {
        List<Type> filteredAttributes = new List<Type>();
        foreach (Attribute at in attributes)
        {

            //    if (at.TypeId.GetType().BaseType == baseType)
            //        filteredAttributes.Add(at.GetType());

            //    if (at.GetType().BaseType == baseType)
            //        filteredAttributes.Add(at.GetType());

        }

        return filteredAttributes;
    }

Invoked with:

            Type test = typeof(DataSource);

            IEnumerable<Attribute> customAttributes = test.GetCustomAttributes();
            List<Type> filteredAttributes = AttributeFilter(customAttributes, test);

Upvotes: 0

Views: 328

Answers (2)

Tim
Tim

Reputation: 6060

Your code is looking at the Type of the attribute itself by calling GetType(), not the Type referred to by the attribute in it's constructor. Try something like this:

public static IEnumerable<Type> GetXmlIncludeTypes(Type type) {
    foreach (var attr in Attribute.GetCustomAttributes(type)) {
        if (attr is XmlIncludeAttribute) {
            yield return ((XmlIncludeAttribute)attr).Type;
        }
    }
}

You would call it like this:

foreach (var t in GetXmlIncludeTypes(typeof(Foo))) {
   //whatever logic you are looking for in the base types
}

Upvotes: 1

djs
djs

Reputation: 1690

First, you want to limit your attributes to just the ones that are XmlIncludeAttribute. Then, you can check the attributes' Type property. So, your function looks like this:

static private List<Type> AttributeFilter(IEnumerable<XmlIncludeAttribute> attributes, Type baseType)
{
    List<Type> filteredAttributes = new List<Type>();
    foreach (XmlIncludeAttribute at in attributes)
    {
        if (at.Type.BaseType == baseType)
        {
            filteredAttributes.Add(at.Type);
        }
    }
    return filteredAttributes;
}

And you can call it like this:

IEnumerable<XmlIncludeAttribute> customAttributes = test.GetCustomAttributes().Where(x => x is XmlIncludeAttribute).Select(x => x as XmlIncludeAttribute);
List<Type> filteredAttributes = AttributeFilter(customAttributes, test);

Upvotes: 1

Related Questions