How do I ignore the inheritance chain when getting attributes?
For some reason I am not getting this. (Model example below) If I write:
var property = typeof(sedan).GetProperty("TurningRadius");
Attribute.GetCustomAttributes(property,typeof(MyAttribute), false)
the call will return MyAttribute (2) even though I don't want to look for the inheritance chain. Does anyone know what code I can write to call
MagicAttributeSearcher(typeof(Sedan).GetProperty("TurningRadius"))
returns nothing when called
MagicAttributeSearcher(typeof(Vehicle).GetProperty("TurningRadius"))
returns MyAttribute (1)?
Model example:
public class Sedan : Car
{
// ...
}
public class Car : Vehicle
{
[MyAttribute(2)]
public override int TurningRadius { get; set; }
}
public abstract class Vehicle
{
[MyAttribute(1)]
public virtual int TurningRadius { get; set; }
}
source to share
Ok, given the additional information - I believe the problem is what GetProperty
goes up the inheritance change.
If you change your call GetProperty
to:
PropertyInfo prop = type.GetProperty("TurningRadius",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
then it prop
will be null if the property is not overridden. For example:
static bool MagicAttributeSearcher(Type type)
{
PropertyInfo prop = type.GetProperty("TurningRadius", BindingFlags.Instance |
BindingFlags.Public | BindingFlags.DeclaredOnly);
if (prop == null)
{
return false;
}
var attr = Attribute.GetCustomAttribute(prop, typeof(MyAttribute), false);
return attr != null;
}
This returns true
and only if:
- The specified type overrides the property
TurningRadius
(or declares a new one) - The property has an attribute
MyAttribute
.
source to share
I believe the problem is when you get the TurningRadius property from the Sedan object on the first line
var property = typeof(sedan).GetProperty("TurningRadius");
what you actually get is a TurningRadius property declared at the Car level since Sedan doesn't have its own overload.
So when you ask for its attributes, you get the ones defined in the car, even if you asked not to climb up the inheritance chain, since the property you are requesting is the one defined in Car.
You have to modify GetProperty to add the required flags to get only member declarations. I believe DeclaredOnly should do.
Edit: Note that this change will have the first line returning null, so watch out for NullPointerExceptions.
source to share
I think this is what you need - note that I had to make TurningRadius abstract in Car and override in Car. This is normal?
using System;
using System.Reflection;
public class MyAttribute : Attribute
{
public MyAttribute(int x) {}
}
public class Sedan : Car
{
// ...
}
public class Car : Vehicle
{
public override int TurningRadius { get; set; }
}
public abstract class Vehicle
{
[MyAttribute(1)]
public virtual int TurningRadius { get; set; }
}
class Program
{
static void Main(string[] args)
{
MagicAttributeSearcher(typeof(Sedan));
MagicAttributeSearcher(typeof(Vehicle));
}
static void MagicAttributeSearcher(Type type)
{
PropertyInfo prop = type.GetProperty("TurningRadius");
var attr = Attribute.GetCustomAttribute(prop, typeof(MyAttribute), false);
Console.WriteLine("{0}: {1}", type, attr);
}
}
Output:
Sedan:
Vehicle: MyAttribute
source to share