Condividi tramite


Attributi

Gli attributi forniscono un metodo efficace per associare metadati o informazioni dichiarative, con codice (assembly, tipi, metodi, proprietà e così via). Dopo che un attributo è associato a un'entità programma, l'attributo può essere sottoposto a query in fase di esecuzione usando una tecnica denominata reflection .

Gli attributi hanno le proprietà seguenti:

  • Gli attributi aggiungono metadati al programma. metadati sono informazioni sui tipi definiti in un programma. Tutti gli assembly .NET contengono un set specificato di metadati che descrivono i tipi e i membri di tipo definiti nell'assembly. È possibile aggiungere attributi personalizzati per specificare eventuali informazioni aggiuntive necessarie.
  • È possibile applicare uno o più attributi a interi assembly, moduli o elementi di programma più piccoli, ad esempio classi e proprietà.
  • Gli attributi possono accettare argomenti nello stesso modo dei metodi e delle proprietà.
  • Il programma può esaminare i propri metadati o i metadati in altri programmi usando reflection.

Reflection fornisce oggetti (di tipo Type) che descrivono assembly, moduli e tipi. È possibile utilizzare la reflection per creare in modo dinamico un'istanza di un tipo, associare il tipo a un oggetto esistente oppure ottenere il tipo da un oggetto esistente e richiamarne i metodi o accedere ai relativi campi e proprietà. Se si usano attributi nel codice, la reflection consente di accedervi. Per altre informazioni, vedere Attributi.

Ecco un semplice esempio di reflection usando il metodo GetType() , ereditato da tutti i tipi dalla classe base Object , per ottenere il tipo di una variabile:

Nota

Assicurarsi di aggiungere using System; e using System.Reflection; nella parte superiore del file di .cs.

// Using GetType to obtain type information:
int i = 42;
Type type = i.GetType();
Console.WriteLine(type);

L'output è: System.Int32.

Nell'esempio seguente viene utilizzata la reflection per ottenere il nome completo dell'assembly caricato.

// Using Reflection to get information of an Assembly:
Assembly info = typeof(int).Assembly;
Console.WriteLine(info);

L'output è simile al seguente: System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e.

Nota

Le parole chiave C# protected e internal non hanno alcun significato nel linguaggio intermedio (IL) e non vengono usate nelle API di reflection. I termini corrispondenti in IL sono Family e Assembly. Per identificare un metodo internal tramite reflection, utilizzare la proprietà IsAssembly. Per identificare un metodo protected internal, usare il IsFamilyOrAssembly.

Uso degli attributi

Gli attributi possono essere inseriti in quasi qualsiasi dichiarazione, anche se un attributo specifico potrebbe limitare i tipi di dichiarazioni su cui è valido. In C# si specifica un attributo inserendo il nome dell'attributo racchiuso tra parentesi quadre ([]) sopra la dichiarazione dell'entità a cui si applica.

In questo esempio, l'attributo SerializableAttribute viene usato per applicare una caratteristica specifica a una classe:

[Serializable]
public class SampleClass
{
    // Objects of this type can be serialized.
}

Un metodo con l'attributo DllImportAttribute viene dichiarato come nell'esempio seguente:

[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static void SampleMethod();

È possibile inserire più attributi in una dichiarazione come illustrato nell'esempio seguente:

void MethodA([In][Out] ref double x) { }
void MethodB([Out][In] ref double x) { }
void MethodC([In, Out] ref double x) { }

Alcuni attributi possono essere specificati più volte per una determinata entità. Un esempio di attributo multiuso di questo tipo è ConditionalAttribute:

[Conditional("DEBUG"), Conditional("TEST1")]
void TraceMethod()
{
    // ...
}

Nota

Per convenzione, tutti i nomi degli attributi terminano con la parola "Attribute" per distinguerli da altri elementi nelle librerie .NET. Tuttavia, non è necessario specificare il suffisso dell'attributo quando si usano attributi nel codice. Ad esempio, [DllImport] equivale a [DllImportAttribute], ma DllImportAttribute è il nome effettivo dell'attributo nella libreria di classi .NET.

Parametri dell'attributo

Molti attributi hanno parametri, che possono essere posizionali, senza nome o denominati. Tutti i parametri posizionali devono essere specificati in un determinato ordine e non possono essere omessi. I parametri denominati sono facoltativi e possono essere specificati in qualsiasi ordine. I parametri posizionali vengono specificati per primi. Ad esempio, questi tre attributi sono equivalenti:

[DllImport("user32.dll")]
[DllImport("user32.dll", SetLastError=false, ExactSpelling=false)]
[DllImport("user32.dll", ExactSpelling=false, SetLastError=false)]

Il primo parametro, il nome della DLL, è posizionale e viene sempre prima; gli altri sono denominati. In questo caso, entrambi i parametri denominati hanno valore predefinito su false, in modo che possano essere omessi. I parametri posizionali corrispondono ai parametri del costruttore dell'attributo. I parametri denominati o facoltativi corrispondono a proprietà o campi dell'attributo. Per informazioni sui valori dei parametri predefiniti, vedere la documentazione dell'attributo singolo.

Per altre informazioni sui tipi di parametro consentiti, vedere la sezione attributi della specifica del linguaggio C# .

Destinazioni degli attributi

Il target di un attributo è l'entità a cui si applica l'attributo. Ad esempio, un attributo può essere applicato a una classe, a un metodo specifico o a un intero assembly. Per impostazione predefinita, un attributo si applica all'elemento che lo segue. Tuttavia, è anche possibile identificare in modo esplicito, ad esempio, se un attributo viene applicato a un metodo o al relativo parametro o al relativo valore restituito.

Per identificare in modo esplicito una destinazione dell'attributo, usare la sintassi seguente:

[target : attribute-list]

L'elenco dei possibili valori target è illustrato nella tabella seguente.

Valore di destinazione Si applica a
assembly Intero assemblaggio
module Modulo corrente di assemblaggio
field Campo in una classe o in una struttura
event Evento
method Funzioni di accesso alle proprietà di metodo o getset e di set
param Parametri del metodo o parametri della funzione di accesso alle proprietà set
property Proprietà
return Valore restituito di un metodo, di un indicizzatore di proprietà o di una funzione di accesso alla proprietà get
type Struct, classe, interfaccia, enumerazione o delegato

Specificare il valore di destinazione field per applicare un attributo al campo sottostante creato per una proprietà implementata automaticamente.

Nell'esempio seguente viene illustrato come applicare attributi agli assembly e ai moduli. Per altre informazioni, vedere attributi comuni (C#).

using System;
using System.Reflection;
[assembly: AssemblyTitleAttribute("Production assembly 4")]
[module: CLSCompliant(true)]

Nell'esempio seguente viene illustrato come applicare attributi a metodi, parametri del metodo e valori restituiti dal metodo in C#.

// default: applies to method
[ValidatedContract]
int Method1() { return 0; }

// applies to method
[method: ValidatedContract]
int Method2() { return 0; }

// applies to parameter
int Method3([ValidatedContract] string contract) { return 0; }

// applies to return value
[return: ValidatedContract]
int Method4() { return 0; }

Nota

Indipendentemente dalle destinazioni in cui ValidatedContract è definito come valido, è necessario specificare la destinazione return, anche se ValidatedContract sono stati definiti per essere applicati solo ai valori restituiti. In altre parole, il compilatore non userà le informazioni AttributeUsage per risolvere ambiguità nei bersagli degli attributi. Per altre informazioni, vedere AttributeUsage.

Usi comuni per gli attributi

L'elenco seguente include alcuni degli usi comuni degli attributi nel codice:

  • Contrassegnare i metodi usando l'attributo WebMethod nei servizi Web per indicare che il metodo deve essere chiamabile tramite il protocollo SOAP. Per altre informazioni, vedere WebMethodAttribute.
  • Descrizione di come gestire il marshalling dei parametri di un metodo nell'interoperabilità con codice nativo. Per altre informazioni, vedere MarshalAsAttribute.
  • Descrizione delle proprietà COM per classi, metodi e interfacce.
  • Chiamata di codice non gestito tramite la classe DllImportAttribute.
  • Descrizione dell'assembly in termini di titolo, versione, descrizione o marchio.
  • Descrizione dei membri di una classe da serializzare per la persistenza.
  • Descrizione di come eseguire il mapping tra i membri della classe e i nodi XML per la serializzazione XML.
  • Descrizione dei requisiti di sicurezza per i metodi.
  • Specifica delle caratteristiche utilizzate per applicare la sicurezza.
  • Controllare le ottimizzazioni dal compilatore JIT (Just-In-Time) in modo che il codice rimanga facile da eseguire.
  • Recupero di informazioni sul chiamante di un metodo.

Panoramica della riflessione

La reflection è utile nelle situazioni seguenti:

Per altre informazioni: