Gareth
Gareth

Reputation: 2791

Get attribute of derived C# class passed as base class to generic method

I'm trying to determine the value of an attribute on a derived class, when it's been passed into a method through a base class parameter.

For example, complete code sample below:

class Program
{
    static void Main(string[] args)
    {
        DerivedClass DC = new DerivedClass();
        ProcessMessage(DC);
    }

    private static void ProcessMessage(BaseClass baseClass)
    {
        Console.WriteLine(GetTargetSystemFromAttribute(baseClass));
        Console.ReadLine();
    }

    private static string GetTargetSystemFromAttribute<T>(T msg)
    {
        TargetSystemAttribute TSAttribute = (TargetSystemAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(TargetSystemAttribute));

        if (TSAttribute == null)
            throw new Exception(string.Format("Message type {0} has no TargetSystem attribute and/or the TargetSystemType property was not set.", typeof(T).ToString()));

        return TSAttribute.TargetSystemType;
    }
}

public class BaseClass
{}

[TargetSystem(TargetSystemType="OPSYS")]
public class DerivedClass : BaseClass
{}

[AttributeUsage(AttributeTargets.Class)]
public sealed class TargetSystemAttribute : Attribute
{
    public string TargetSystemType { get; set; }
}

So, in the above example, I had intended that the generic GetTargetSystemFromAttribute method returns "OPSYS".

But, because the DerivedClass instance has been passed to ProcessMessage as the base class, Attribute.GetAttribute is not finding anything because it's treating the DerivedClass as the Base Class, which does not have the attribute or the value I'm interested in.

In the real-world there are dozens of Derived Classes, so I was hoping to avoid lots of:

if (baseClass is DerivedClass)

...which is suggested as the answer in the question How to access the properties of an instance of a derived class which is passed as a parameter in the form of the base class (which relates to a similar issue, but with properties). I was hoping because I'm interested in Attributes there's a nicer way of doing it, especially as I have dozens of derived classes.

So, here's the question. Is there any way I can obtain the TargetSystemType value of the TargetSystem Attribute on my derived classes in a low-maintenance way?

Upvotes: 9

Views: 8536

Answers (1)

Lev
Lev

Reputation: 3924

You should change this line:

(TargetSystemAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(TargetSystemAttribute));

with this:

msg.GetType().GetCustomAttributes(typeof(TargetSystemAttribute), true)[0] as TargetSystemAttribute;

P.S. GetCustomAttributes returns array and I picked up first element for example where only 1 attribute is expected, you may need to change, but the logic is the same.

Upvotes: 11

Related Questions