2

Attribute constructors are called after calling GetCustomAttributes() on a type that is decorated with attributes. Is it possible to determine the calling type from within the constructor. I would like to do something similar to the following and have it not throw.

class Program
{
    static void Main(string[] args)
    {
        var myAttributedClassType = typeof(MyAttributedClass);
        var customAttributes = myAttributedClassType.GetCustomAttributes(false)
                                                    .OfType<MyAttribute>();
        if (customAttributes.Any(x => x.CallingType != myAttributedClassType))
        {
            throw new Exception("MyAttribute.CallingType was incorrect.");
        }
    }
}

[AttributeUsage(AttributeTargets.Class)]
class MyAttribute : Attribute
{
    public Type CallingType { get; set; }

    public MyAttribute()
    {
        // magic to set CallingType goes here
    }
}

[MyAttribute]
class MyAttributedClass { }

UPDATE:

I know that this can be done easily through named parameters in the constructor

[MyAttribute(CallingType = typeof(MyAttributedClass)

or a required parameter

public MyAttributed(Type callingType)
{
    CallingType = callingType;    // this doesn't qualify as magic ;)
}

but was hoping there was a way to avoid it since the type object itself (the value I want) is the caller of GetCustomAttributes

mhand
  • 1,231
  • 1
  • 11
  • 21
  • http://stackoverflow.com/questions/1235617/how-to-pass-objects-into-an-attribute-constructor you can pass type to the attribute constructor – cheedep May 23 '13 at 21:43
  • 2
    No nice ways. You might able to do some things with stack trace / frames, but nothing pretty – Marc Gravell May 23 '13 at 21:44
  • @cheedep I was trying to avoid passing the type in since there may be cases of many of these on a single type, it just looks overly redundant. – mhand May 23 '13 at 21:47
  • @MarcGravell thanks, that's what I figured. – mhand May 23 '13 at 21:53
  • you could do it with postsharp (see http://stackoverflow.com/questions/7851365/how-to-inject-an-attribute-using-a-postsharp-attribute) but it uses some compile time magic to do the same thing behind the scenes. – Yaur May 23 '13 at 22:50

1 Answers1

0

Your magic, not really magic though:

[AttributeUsage(AttributeTargets.Class)]
class MyAttribute : Attribute
{
    public Type CallingType { get; set; }

    public MyAttribute(Type type)
    {
       // heres your magic
       this.CallingType = type;
    }
}

Usage:

[MyAttribute(typeof(MyClass))]
Gabe
  • 49,577
  • 28
  • 142
  • 181