Reputation: 77288
For some reason I'm not getting this. (Example model below) If I write:
var property = typeof(sedan).GetProperty("TurningRadius");
Attribute.GetCustomAttributes(property,typeof(MyAttribute), false)
the call will return MyAttribute(2) despite indicating I don't want to search the inheritance chain. Does anyone know what code I can write so that calling
MagicAttributeSearcher(typeof(Sedan).GetProperty("TurningRadius"))
returns nothing while calling
MagicAttributeSearcher(typeof(Vehicle).GetProperty("TurningRadius"))
returns MyAttribute(1)?
Example Model:
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; }
}
Upvotes: 2
Views: 873
Reputation: 1500185
Okay, given the extra information - I believe the problem is that GetProperty
is going up the inheritance change.
If you change your call to GetProperty
to:
PropertyInfo prop = type.GetProperty("TurningRadius",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
then prop
will be null if the property isn't overridden. For instance:
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:
TurningRadius
property (or declares a new one)MyAttribute
attribute.Upvotes: 5
Reputation: 3542
I believe the problem is that when you obtain the property TurningRadius from the Sedan object in the first line
var property = typeof(sedan).GetProperty("TurningRadius");
what you are actually getting is the TurningRadius property declared at Car level, since Sedan doesn't have its own overload.
Therefore, when you request its attributes, you are getting the ones defined at car even if you requested not to go up in the inheritance chain, as the property you are querying is the one defined in Car.
You should change the GetProperty to add the necessary flags to obtain only declaring members. I believe DeclaredOnly should do.
Edit: Note that this change will have the first line return null, so watch out for NullPointerExceptions.
Upvotes: 3
Reputation: 1500185
I think this is what you're after - note that I had to make TurningRadius abstract in Vehicle and overridden in Car. Is that okay?
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
Upvotes: 1