9

考虑以下场景:

  • 基属性类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
  {
  }
}

在这种情况下,GetCustomAttributesAPI 返回DerivedAttribute该类的一个实例。我本来希望它不会返回该实例,因为http://msdn.microsoft.com/en-us/library/system.attributeusageattribute.aspx说它AttributeUsageAttribute本身是可继承的。

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

注(2013-02-20):实验表明,类的AttributeTargets部分BaseAttribute确实是类继承的DerivedAttribute。例如,当我将允许的目标更改为 时BaseAttributeAttributeTargets.MethodC# 编译器将不允许我应用DerivedAttribute到一个类。因此,该Inherited = false部分不被 继承是没有意义的,DerivedAttribute因此我倾向于认为GetCustomAttributes.

4

1 回答 1

0

根据 .NET 4.0 中的元数据,AttributeUsageAttribute该类被标记为[AttributeUsage(AttributeTargets.Class, Inherited = true)]. 所以,如果你的属性类(BaseAttribute在你的例子中),有一个AttributeUsageAttribute应用到它(所有Attribute类都应该,但如果他们没有 - 见下文,不要破坏任何东西),那么任何派生的类都BaseAttribute应该继承AttributeUsage应用的属性给它。

你的Derived类继承DerivedAttribute自 Base,因为DerivedAttribute没有AttributeUsageAttribute应用它自己的类,所以反射 API 依赖于BaseAttribute's 属性。现在,去掉AttributeUsageAttribute你的BaseAttribute类,你会得到同样的结果,因为基System.Attribute类用[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = false)]. 因此,任何属性类都将继承此属性,除非您指定不同的属性。

哇,这些都是复杂的段落。属性上的属性让人读起来很重:P

于 2015-01-12T09:01:28.237 回答