Destinazioni degli attributi (C++/CLI e C++/CX)

Gli specificatori di utilizzo degli attributi consentono di specificare le destinazioni degli attributi. Ogni attributo viene definito per essere applicato a determinati elementi del linguaggio. Ad esempio, un attributo potrebbe essere definito per essere applicato solo alle classi e agli struct. Nell'elenco seguente vengono mostrati i possibili elementi sintattici per cui può essere utilizzato un attributo personalizzato. È possibile utilizzare combinazioni di questi valori (tramite l'OR logico).

Per specificare la destinazione dell'attributo, passare uno o più enumeratori AttributeTargets a AttributeUsageAttribute durante la definizione dell'attributo.

Di seguito è riportato un elenco di destinazioni degli attributi valide:

  • All (si applica a tutti i costrutti)

    using namespace System;
    [AttributeUsage(AttributeTargets::All)]
    ref class Attr : public Attribute {};
    
    [assembly:Attr];
    
  • Assembly (si applica a un assembly nel suo complesso)

    using namespace System;
    [AttributeUsage(AttributeTargets::Assembly)]
    ref class Attr : public Attribute {};
    
    [assembly:Attr];
    
  • Module (si applica a un modulo nel suo complesso)

    using namespace System;
    [AttributeUsage(AttributeTargets::Module)]
    ref class Attr : public Attribute {};
    
    [module:Attr];
    
  • Class

    using namespace System;
    [AttributeUsage(AttributeTargets::Class)]
    ref class Attr : public System::Attribute {};
    
    [Attr]   // same as [class:Attr]
    ref class MyClass {};
    
  • Struct

    using namespace System;
    [AttributeUsage(AttributeTargets::Struct)]
    ref class Attr : public Attribute {};
    
    [Attr]   // same as [struct:Attr]
    value struct MyStruct{};
    
  • enum

    using namespace System;
    [AttributeUsage(AttributeTargets::Enum)]
    ref class Attr : public Attribute {};
    
    [Attr]   // same as [enum:Attr]
    enum struct MyEnum{e, d};
    
  • Constructor

    using namespace System;
    [AttributeUsage(AttributeTargets::Constructor)]
    ref class Attr : public Attribute {};
    
    ref struct MyStruct{
    [Attr] MyStruct(){}   // same as [constructor:Attr]
    };
    
  • Method

    using namespace System;
    [AttributeUsage(AttributeTargets::Method)]
    ref class Attr : public Attribute {};
    
    ref struct MyStruct{
    [Attr] void Test(){}   // same as [method:Attr]
    };
    
  • Property

    using namespace System;
    [AttributeUsage(AttributeTargets::Property)]
    ref class Attr : public Attribute {};
    
    ref struct MyStruct{
    [Attr] property int Test;   // same as [property:Attr]
    };
    
  • Field

    using namespace System;
    [AttributeUsage(AttributeTargets::Field)]
    ref class Attr : public Attribute {};
    
    ref struct MyStruct{
    [Attr] int Test;   // same as [field:Attr]
    };
    
  • Event

    using namespace System;
    [AttributeUsage(AttributeTargets::Event)]
    ref class Attr : public Attribute {};
    
    delegate void ClickEventHandler(int, double);
    
    ref struct MyStruct{
    [Attr] event ClickEventHandler^ OnClick;   // same as [event:Attr]
    };
    
  • Interface

    using namespace System;
    [AttributeUsage(AttributeTargets::Interface)]
    ref class Attr : public Attribute {};
    
    [Attr]   // same as [event:Attr]
    interface struct MyStruct{};
    
  • Parameter

    using namespace System;
    [AttributeUsage(AttributeTargets::Parameter)]
    ref class Attr : public Attribute {};
    
    ref struct MyStruct{
    void Test([Attr] int i);
    void Test2([parameter:Attr] int i);
    };
    
  • Delegate

    using namespace System;
    [AttributeUsage(AttributeTargets::Delegate)]
    ref class Attr : public Attribute {};
    
    [Attr] delegate void Test();
    [delegate:Attr] delegate void Test2();
    
  • ReturnValue

    using namespace System;
    [AttributeUsage(AttributeTargets::ReturnValue)]
    ref class Attr : public Attribute {};
    
    ref struct MyStruct {
    // Note required specifier
    [returnvalue:Attr] int Test() { return 0; }
    };
    

In genere, un attributo precede direttamente l'elemento del linguaggio a cui si applica. In alcuni casi, tuttavia, la posizione di un attributo non è sufficiente per determinare la relativa destinazione prevista. Si consideri questo esempio:

[Attr] int MyFn(double x)...

Da un punto di vista sintattico, non è possibile dire se l'attributo è progettato per essere applicato al metodo o al valore restituito del metodo (in questo caso, è impostato in modo predefinito sul metodo). In questi casi, è possibile utilizzare un identificatore di utilizzo degli attributi. Ad esempio, per fare in modo che l'attributo si applichi al valore restituito, utilizzare l'identificatore returnvalue come riportato di seguito:

[returnvalue:Attr] int MyFn(double x)... // applies to return value

Gli identificatori di utilizzo degli attributi sono obbligatori nelle situazioni seguenti:

  • Per specificare un attributo a livello di modulo o di assembly.

  • Per specificare che un attributo viene applicato al valore restituito di un metodo e non al metodo:

    [method:Attr] int MyFn(double x)...     // Attr applies to method
    [returnvalue:Attr] int MyFn(double x)...// Attr applies to return value
    [Attr] int MyFn(double x)...            // default: method
    
  • Per specificare che un attributo viene applicato alla funzione di accesso di una proprietà e non alla proprietà:

    [method:MyAttr(123)] property int Property()
    [property:MyAttr(123)] property int Property()
    [MyAttr(123)] property int get_MyPropy() // default: property
    
  • Per specificare che un attributo viene applicato alla funzione di accesso di un evento e non all'evento:

    delegate void MyDel();
    ref struct X {
       [field:MyAttr(123)] event MyDel* MyEvent;   //field
       [event:MyAttr(123)] event MyDel* MyEvent;   //event
       [MyAttr(123)] event MyDel* MyEvent;   // default: event
    }
    

Un identificatore di utilizzo degli attributi si applica solo all'attributo immediatamente successivo, cioè

[returnvalue:Attr1, Attr2]

è diverso da

[returnvalue:Attr1, returnvalue:Attr2]

Esempio

Descrizione

In questo esempio viene illustrato come specificare più destinazioni.

Codice

using namespace System;
[AttributeUsage(AttributeTargets::Class | AttributeTargets::Struct, AllowMultiple = true )]
ref struct Attr : public Attribute {
   Attr(bool i){}
   Attr(){}
};

[Attr]
ref class MyClass {};

[Attr]
[Attr(true)]
value struct MyStruct {};

Vedi anche

Attributi definiti dall'utente