获取属性时如何忽略继承链?

时间:2008-11-07 23:09:28

标签: c# reflection attributes

出于某种原因,我没有得到这个。 (下面的示例模型)如果我写:

var property = typeof(sedan).GetProperty("TurningRadius");
Attribute.GetCustomAttributes(property,typeof(MyAttribute), false)

尽管指示我不想搜索继承链,但该调用将返回MyAttribute(2)。有谁知道我可以编写什么代码,以便调用

MagicAttributeSearcher(typeof(Sedan).GetProperty("TurningRadius"))

在调用

时不返回任何内容
MagicAttributeSearcher(typeof(Vehicle).GetProperty("TurningRadius"))

返回MyAttribute(1)?


示例模型:

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

3 个答案:

答案 0 :(得分:4)

好的,鉴于额外的信息 - 我认为问题是GetProperty正在进行继承更改。

如果您将对GetProperty的通话更改为:

PropertyInfo prop = type.GetProperty("TurningRadius",
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);

如果未覆盖该属性,则prop将为null。例如:

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

仅在以下情况下返回true

  • 指定的类型会覆盖TurningRadius属性(或声明一个新属性)
  • 该属性具有MyAttribute属性。

答案 1 :(得分:3)

我相信问题是当你从第一行的Sedan对象中获取属性TurningRadius时

var property = typeof(sedan).GetProperty("TurningRadius");

你实际获得的是在Car级别声明的TurningRadius属性,因为Sedan没有自己的重载。

因此,当您请求其属性时,即使您请求不在继承链中,也会获得在汽车中定义的属性,因为您要查询的属性是Car中定义的属性。

您应该更改GetProperty以添加必要的标志以仅获取声明成员。我相信DeclaredOnly应该这样做。

编辑:请注意,此更改将使第一行返回null,因此请注意NullPointerExceptions。

答案 2 :(得分:1)

我认为这就是你所追求的 - 请注意我必须在Vehicle中将TurningRadius抽象化并在Car中重写。那可以吗?

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

输出:

Sedan:
Vehicle: MyAttribute