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; }
}

      

+1


source to share


3 answers


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

    .
+4


source


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.

+3


source


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

      

+1


source







All Articles