Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 585
Gareth Avatar asked Sep 19 '13 15:09

Gareth


People also ask

Are attributes inherited?

When you associate an attribute with a product class, it is inherited by all member subclasses. If you edit an attribute on the product class where it was originally defined, the changes propagate to all member subclasses. The attribute definition is uniform for all subclasses that inherit it.

What can derived class inherit?

A derived class inherits member functions of base class. A derived class can be used anywhere the base class is expected. A derived class inherits member functions of base class.

Can derived classes access private variables?

Private members can only be accessed by member functions of the same class or friends. This means derived classes can not access private members of the base class directly!

Do derived classes inherit members?

The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. A derived class can have only one direct base class.


1 Answers

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.

like image 84
Lev Avatar answered Oct 06 '22 19:10

Lev