Dela via


Attribut

Attribut är ett kraftfullt sätt att associera metadata eller deklarativ information med kod (sammansättningar, typer, metoder, egenskaper och så vidare). När du har associerat ett attribut med en programentitet kan du köra frågor mot attributet vid körning med hjälp av en teknik som kallas reflektion.

Attribut har följande egenskaper:

  • Attribut lägger till metadata i ditt program. metadata är information om de typer som definierats i ett program. Alla .NET-sammansättningar innehåller en angiven uppsättning metadata som beskriver de typer och typmedlemmar som definierats i sammansättningen. Du kan lägga till anpassade attribut för att ange annan nödvändig information.
  • Attribut kan tillämpas på hela sammansättningar, moduler eller mindre programelement, till exempel klasser och egenskaper.
  • Attribut kan acceptera argument på samma sätt som metoder och egenskaper.
  • Med attribut kan ett program undersöka sina egna metadata eller metadata i andra program med hjälp av reflektion.

Arbeta med reflektion

Reflektion API:er som tillhandahålls av Type beskriv sammansättningar, moduler och typer. Du kan använda reflektion för att dynamiskt skapa en instans av en typ, binda typen till ett befintligt objekt eller hämta typen från ett befintligt objekt och anropa dess metoder eller komma åt dess fält och egenskaper. När du använder attribut i koden kan du med reflektion komma åt dem. Mer information finns i Attribut.

Här är ett enkelt exempel på reflektion med GetType() metoden. Alla typer från den basklassen Object ärver denna metod, som används för att hämta typen av en variabel:

Obs

Se till att du lägger till using System; -instruktionerna och using System.Reflection; överst i C#-kodfilen (.cs).

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

Utdata visar typen:

System.Int32

I följande exempel används reflektion för att hämta det fullständiga namnet på den inlästa sammansättningen.

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

Utdata ser ut ungefär så här:

System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e

Nyckelordsskillnader för IL

C#-nyckelorden protected och internal har ingen betydelse i mellanliggande språk (IL) och används inte i reflektions-API:erna. Motsvarande termer i IL är Family och Assembly. Här är några sätt att använda dessa termer:

  • Om du vill identifiera en internal metod med reflektion använder du egenskapen IsAssembly .
  • Om du vill identifiera en protected internal-metod använder du IsFamilyOrAssembly.

Arbeta med attribut

Attribut kan placeras på nästan vilken deklaration som helst, även om ett specifikt attribut kan begränsa de typer av deklarationer som den är giltig för. I C# anger du ett attribut genom att placera namnet på attributet inom hakparenteser ([]) ovanför deklarationen för den entitet som det gäller för.

I det här exemplet använder SerializableAttribute du attributet för att tillämpa en specifik egenskap på en klass:

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

Du kan deklarera en metod med attributet DllImportAttribute :

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

Du kan placera flera attribut i en deklaration:

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

Vissa attribut kan anges mer än en gång för en viss entitet. I följande exempel visas multianvändningen av attributet ConditionalAttribute :

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

Obs

Enligt konventionen slutar alla attributnamn med suffixet "Attribut" för att skilja dem från andra typer i .NET-biblioteken. Du behöver dock inte ange attributsuffixet när du använder attribut i kod. Till exempel motsvarar en [DllImport]-deklaration en [DllImportAttribute]-deklaration, men DllImportAttribute är det faktiska namnet på klassen i .NET-klassbiblioteket.

Attributparametrar

Många attribut har parametrar som kan vara positionella, namnlösa eller namngivna. I följande tabell beskrivs hur du arbetar med namngivna och positionella attribut:

Positionella parametrar

Parametrar för attributkonstruktorn:

Namngivna parametrar

Egenskaper eller fält för attributet:

  • Måste ange, kan inte utelämna
  • Ange alltid först
  • Ange i viss ordning
  • Alltid valfritt, utelämna när falskt
  • Ange efter positionsparametrar
  • Ange i valfri ordning

Följande kod visar till exempel tre motsvarande DllImport attribut:

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

Den första parametern, DLL-namnet, är positionell och kommer alltid först. De andra instanserna heter parametrar. I det här scenariot har båda namngivna parametrar standardvärdet false, så de kan utelämnas. Information om standardparametervärden finns i dokumentationen för det enskilda attributet. Mer information om tillåtna parametertyper finns i avsnittet Attribut i C#-språkspecifikationen.

Mål för attribut

målobjektet för ett attribut är den entitet som attributet gäller för. Ett attribut kan till exempel gälla för en klass, en metod eller en sammansättning. Som standard gäller ett attribut för elementet som följer det. Men du kan också uttryckligen identifiera elementet som ska associeras, till exempel en metod, en parameter eller returvärdet.

Om du uttryckligen vill identifiera ett attributmål använder du följande syntax:

[target : attribute-list]

I följande tabell visas en lista över möjliga target värden.

Målvärde Gäller för
assembly Hela sammansättningen
module Aktuell sammansättningsmodul
field Fält i en klass eller en struktur
event Händelse
method Metod- eller egenskapsåtkomster för get och set
param Metodparametrar eller set egenskapsåtkomstparametrar
property Egenskap
return Returvärde för en metod, egenskapsindexerare eller get egenskapsaccessor
type Struktur, klass, gränssnitt, uppräkning eller delegering

Du kan ange field målvärdet för att tillämpa ett attribut på det bakgrundsfält som skapats för en automatiskt implementerad egenskap.

I följande exempel visas hur du tillämpar attribut på sammansättningar och moduler. Mer information finns i Vanliga attribut (C#).

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

I följande exempel visas hur du tillämpar attribut på metoder, metodparametrar och metodreturvärden i 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; }

Obs

Oavsett vilka mål som ValidatedContract-attributet är definierat som giltigt för, måste return-målet anges, även om ValidatedContract-attributet definieras att endast gälla för returnerade värden. Kompilatorn använder AttributeUsage med andra ord inte informationen för att lösa tvetydiga attributmål. Mer information finns i AttributeUsage.

Granska sätt att använda attribut

Här är några vanliga sätt att använda attribut i kod:

  • Markera kontrollantmetoder som svarar på POST-meddelanden med hjälp av attributet HttpPost . Mer information finns i HttpPostAttribute klassen .
  • Beskriv hur du överför metodparametrar när du integrerar med inbyggd kod. Mer information finns i MarshalAsAttribute klassen .
  • Beskriv COM-egenskaper (Component Object Model) för klasser, metoder och gränssnitt.
  • Anropa ohanterad kod med hjälp av DllImportAttribute-klassen.
  • Beskriv din sammansättning när det gäller titel, version, beskrivning eller varumärke.
  • Beskriv vilka medlemmar i en klass som ska serialiseras för beständighet.
  • Beskriv hur du mappar mellan klassmedlemmar och XML-noder för XML-serialisering.
  • Beskriv säkerhetskrav för metoder.
  • Ange egenskaper som används för att framtvinga säkerhet.
  • Kontrollera optimeringar med jit-kompilatorn (just-in-time) så att koden förblir lätt att felsöka.
  • Hämta information om anroparen från en viss metod.

Granska reflektionsscenarier

Reflektion är användbart i följande scenarier: