Get the type an attribute is defined on.

S

Steve

Is there a way to get the type information for the class an attribute is
defined on at runtime? I tried getting the attribute type, and then
checking the DeclaringType property but it was null.

Example:

[Cool]
public class Test {}

[AttributeUsage(AttributeTargets.Class)]
public class CoolAttribute : Attribute {
public CoolAttribute() {
Type implementingClass = this.GetType().someFunction;
//implementingClass should now be the Type information for Test
}
}

Surely there has to be a way to do this, and I just can't figure it out.
If it's not possible, can anyone explain why, and what the limitation is
that prevents this?

Thanks,
Steve
 
D

Derrick Coetzee [MSFT]

Steve said:
Is there a way to get the type information for the class an attribute is
defined on at runtime? I tried getting the attribute type, and then
checking the DeclaringType property but it was null.

The DeclaringType property is null because it only applies to members. The
type information for a class - including a class derived from Attribute -
will always be null.
public CoolAttribute() {
Type implementingClass = this.GetType().someFunction;
//implementingClass should now be the Type information for Test
}

Unfortunately, I'm not aware of any member of Attribute that will do this.
Classes track their attributes, but not vice versa, since the usual usage
pattern is to check the attributes of a class you're examining. Your best
bet may be to simply loop through all classes in the assembly (there aren't
that many really) and find all the ones with the attribute you desire on
them, as in this C# 2.0 sample code:

using System;
using System.Collections.Generic;
using System.Reflection;

namespace ConsoleApplication2
{
[Cool]
public class Test { }

[Cool]
public class Foo { }

[AttributeUsage(AttributeTargets.Class)]
public class CoolAttribute : Attribute { }

class Program
{
static List<Type> FindAttributeUsers(Attribute attr)
{
List<Type> result = new List<Type>();
Type[] allTypes = Assembly.GetExecutingAssembly().GetTypes();
foreach(Type type in allTypes)
{
if (Attribute.GetCustomAttribute(type, attr.GetType()) !=
null)
{
result.Add(type);
}
}
return result;
}

static void Main(string[] args)
{
List<Type> coolClasses = FindAttributeUsers(new
CoolAttribute());
foreach (Type type in coolClasses)
{
Console.WriteLine(type.Name + " is cool.");
}
}
}
}

I hope this helps.
 
J

Joakim Karlsson

When is this necessary?

AFAIK the only way to instantiate a custom class attribute is by having
a type in the first place and then ask for the custom attributes
associated with that type via the Attribute.GetCustomAttribute(s)
methods. If you have a custom class attribute, you always already know
the type it applies to.

You could however just add a type to the attribute's constructor:

[Cool(typeof(Test))]
public class Test {}

But I don't really see the point.

/Joakim
 
S

Steve

Joakim said:
When is this necessary?

AFAIK the only way to instantiate a custom class attribute is by having
a type in the first place and then ask for the custom attributes
associated with that type via the Attribute.GetCustomAttribute(s)
methods. If you have a custom class attribute, you always already know
the type it applies to.

You could however just add a type to the attribute's constructor:

[Cool(typeof(Test))]
public class Test {}

But I don't really see the point.

Yes, you're absolutely correct, but the idea is that typeof(SomeClass)
wouldn't have to be done every time, for every class. It's more of a
simplification thing. If someone accidentally mistyped the class
name(for whatever reason) in the typeof() call, their could be huge
ramifications in the rest of the application.

Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top