自定义属性类是否继承“Inherited”AttributeUsage标志?

时间:2013-02-19 10:39:57

标签: c# reflection custom-attributes

考虑以下情况:

  • 基本属性类BaseAttribute有一个AttributeUsageAttribute,指明它不可继承(Inherited = False)。
  • 派生属性类DerivedAttribute继承自该基本属性类。
  • 基础域类Base已应用派生属性。
  • 要求从基本域类继承的域类Derived的自定义 属性,包括继承的属性(inherit: true)。

以下是相应的代码:

using System;
using System.Linq;

namespace ConsoleApplication26
{
  class Program
  {
    static void Main ()
    {
      var attributes = typeof (Derived).GetCustomAttributes (true);
      foreach (var attribute in attributes)
      {
        Console.WriteLine (
            "{0}: Inherited = {1}",
            attribute.GetType().Name,
            attribute.GetType().GetCustomAttributes (typeof (AttributeUsageAttribute), true).Cast<AttributeUsageAttribute>().Single().Inherited);
      }
    }
  }

  [AttributeUsage (AttributeTargets.All, Inherited = false)]
  public class BaseAttribute : Attribute
  {
  }

  public class DerivedAttribute : BaseAttribute
  {
  }

  [Derived]
  public class Base
  {
  }

  public class Derived : Base
  {
  }
}

在这种情况下,GetCustomAttributes API会返回DerivedAttribute类的实例。我原以为它不会返回该实例,因为http://msdn.microsoft.com/en-us/library/system.attributeusageattribute.aspx表示AttributeUsageAttribute本身是可继承的。

现在,这是一个错误,还是在某处预期/记录?

注释(2013-02-20):实验表明AttributeTargets类的BaseAttribute部分确实是由DerivedAttribute类继承的。例如,当我将BaseAttribute上的允许目标更改为AttributeTargets.Method时,C#编译器将不允许我将DerivedAttribute应用于类。因此,Inherited = false部分不会被DerivedAttribute继承而没有意义,因此我倾向于考虑GetCustomAttributes的实现中的错误。

1 个答案:

答案 0 :(得分:0)

根据.NET 4.0中的元数据,AttributeUsageAttribute类标有[AttributeUsage(AttributeTargets.Class, Inherited = true)]。因此,如果您的属性类(在您的示例中为BaseAttribute)已应用AttributeUsageAttribute(因为所有Attribute类应该如此,但如果不属于 - 见下文),然后来自BaseAttribute的任何类都应继承适用于它的AttributeUsage属性。

您的Derived类继承了Base的DerivedAttribute,因为DerivedAttribute没有应用自己的AttributeUsageAttribute,因此反射API依赖BaseAttribute }的属性。现在,从AttributeUsageAttribute班级BaseAttribute开始,您会得到相同的结果,因为基础System.Attribute类标有[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = false)]。因此,除非您指定另一个属性类,否则任何属性类都将继承此属性。

哇,那些是复杂的段落。属性上的属性会产生一些重读:P