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?
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.
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.
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!
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With