9

次のシナリオを検討してください。

  • 基本属性クラスには、継承可能ではないBaseAttributeという指定があります ( )。AttributeUsageAttributeInherited = 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.aspxAttributeUsageAttributeはそれ自体が継承可能であると述べているため、そのインスタンスが返されないと予想していました。

さて、これはバグですか、それとも予想される/どこかに文書化されていますか?

注 (2013-02-20):実験AttributeTargetsでは、クラスの一部BaseAttributeが実際にクラスによって継承されることが示されていDerivedAttributeます。たとえば、許可されたターゲットを に変更するBaseAttributeと、C# コンパイラはクラスAttributeTargets.Methodへの適用を許可しません。DerivedAttributeしたがって、そのInherited = false部分が に継承されないということは意味がなくDerivedAttribute、 の実装にバグがあると考えがちですGetCustomAttributes

4

1 に答える 1

0

.NET 4.0 のメタデータによると、AttributeUsageAttributeクラスは でマークされてい[AttributeUsage(AttributeTargets.Class, Inherited = true)]ます。したがって、属性クラス (BaseAttribute例では ) にAttributeUsageAttribute適用されている場合 (すべてのAttributeクラスがそうであるように、ただし、以下に表示されていない場合は何も壊さないでください)、派生元のクラスは適用されたその属性BaseAttributeを継承する必要があります。AttributeUsageそれに。

独自のクラスが適用されていないため、クラスは Base からDerived継承されます。そのため、リフレクション API はの属性に依存しています。ここで、クラスを削除すると、基本クラスが でマークされているため、同じ結果が得られます。したがって、別の属性を指定しない限り、どの属性クラスもこの属性を継承します。DerivedAttributeDerivedAttributeAttributeUsageAttributeBaseAttributeAttributeUsageAttributeBaseAttributeSystem.Attribute[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = false)]

うわー、それらは複雑な段落です。属性の属性は、いくつかの重い読み物になります:P

于 2015-01-12T09:01:28.237 に答える