Kenmerken
Kenmerken bieden een krachtige methode voor het koppelen van metagegevens of declaratieve informatie, met code (assembly's, typen, methoden, eigenschappen, enzovoort). Nadat een kenmerk is gekoppeld aan een programma-entiteit, kan het kenmerk tijdens runtime worden opgevraagd met behulp van een techniek genaamd reflectie.
Kenmerken hebben de volgende eigenschappen:
- Kenmerken voegen metagegevens toe aan uw programma. Metagegevens is informatie over de typen die in een programma zijn gedefinieerd. Alle .NET-assembly's bevatten een opgegeven set metagegevens waarmee de typen en typeleden worden beschreven die in de assembly zijn gedefinieerd. U kunt aangepaste kenmerken toevoegen om eventuele aanvullende informatie op te geven die vereist is.
- U kunt een of meer kenmerken toepassen op volledige assembly's, modules of kleinere programma-elementen, zoals klassen en eigenschappen.
- Kenmerken kunnen argumenten op dezelfde manier accepteren als methoden en eigenschappen.
- Uw programma kan zijn eigen metagegevens of metagegevens in andere programma's onderzoeken met behulp van weerspiegeling.
Reflectie biedt objecten (van het type Type) die assemblies, modules en typen beschrijven. U kunt reflectie gebruiken om dynamisch een exemplaar van een type te maken, het type aan een bestaand object te binden of het type op te halen uit een bestaand object en de methoden ervan aan te roepen of toegang te krijgen tot de velden en eigenschappen. Als u attributen in uw code gebruikt, stelt reflectie u in staat om toegang te krijgen tot deze attributen. Zie Kenmerkenvoor meer informatie.
Hier volgt een eenvoudig voorbeeld van weerspiegeling met behulp van de methode GetType(), overgenomen door alle typen uit de Object
basisklasse, om het type van een variabele te verkrijgen:
Notitie
Zorg ervoor dat u using System;
en using System.Reflection;
boven aan het .cs-bestand toevoegt.
// Using GetType to obtain type information:
int i = 42;
Type type = i.GetType();
Console.WriteLine(type);
De uitvoer is: System.Int32
.
In het volgende voorbeeld wordt reflectie gebruikt om de volledige naam van de geladen assembly te achterhalen.
// Using Reflection to get information of an Assembly:
Assembly info = typeof(int).Assembly;
Console.WriteLine(info);
De uitvoer ziet er ongeveer als volgt uit: System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
.
Notitie
De C#-trefwoorden protected
en internal
hebben geen betekenis in tussenliggende taal (IL) en worden niet gebruikt in de reflectie-API's. De bijbehorende termen in IL zijn Family en Assembly. Gebruik de eigenschap IsAssembly om een internal
methode te identificeren met behulp van weerspiegeling. Gebruik de IsFamilyOrAssemblyom een protected internal
methode te identificeren.
Kenmerken gebruiken
Kenmerken kunnen op vrijwel elke declaratie worden geplaatst, hoewel een specifiek kenmerk de typen declaraties kan beperken waarop deze geldig is. In C# geeft u een kenmerk op door de naam van het kenmerk tussen vierkante haken ([]
) te plaatsen boven de declaratie van de entiteit waarop het van toepassing is.
In dit voorbeeld wordt het kenmerk SerializableAttribute gebruikt om een specifiek kenmerk toe te passen op een klasse:
[Serializable]
public class SampleClass
{
// Objects of this type can be serialized.
}
Een methode met het kenmerk DllImportAttribute wordt gedeclareerd zoals in het volgende voorbeeld:
[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static void SampleMethod();
Er kunnen meer dan één kenmerk worden geplaatst op een declaratie, zoals in het volgende voorbeeld wordt weergegeven:
void MethodA([In][Out] ref double x) { }
void MethodB([Out][In] ref double x) { }
void MethodC([In, Out] ref double x) { }
Sommige kenmerken kunnen meerdere keren worden opgegeven voor een bepaalde entiteit. Een voorbeeld van een dergelijk multiusekenmerk is ConditionalAttribute:
[Conditional("DEBUG"), Conditional("TEST1")]
void TraceMethod()
{
// ...
}
Notitie
Volgens de conventie eindigen alle kenmerknamen met het woord 'Kenmerk' om ze te onderscheiden van andere items in de .NET-bibliotheken. U hoeft echter niet het kenmerkachtervoegsel op te geven wanneer u kenmerken in code gebruikt.
[DllImport]
is bijvoorbeeld gelijk aan [DllImportAttribute]
, maar DllImportAttribute
de werkelijke naam van het kenmerk is in de .NET-klassebibliotheek.
Kenmerkparameters
Veel kenmerken hebben parameters, die positioneel, naamloos of benoemd kunnen zijn. Eventuele positionele parameters moeten in een bepaalde volgorde worden opgegeven en kunnen niet worden weggelaten. Benoemde parameters zijn optioneel en kunnen in elke volgorde worden opgegeven. Positionele parameters worden eerst opgegeven. Deze drie kenmerken zijn bijvoorbeeld gelijkwaardig:
[DllImport("user32.dll")]
[DllImport("user32.dll", SetLastError=false, ExactSpelling=false)]
[DllImport("user32.dll", ExactSpelling=false, SetLastError=false)]
De eerste parameter, de DLL-naam, is positioneel en komt altijd als eerste; de andere parameters zijn benoemd. In dit geval worden beide benoemde parameters standaard ingesteld op false, zodat ze kunnen worden weggelaten. Positionele parameters komen overeen met de parameters van de kenmerkconstructor. Benoemde of optionele parameters komen overeen met eigenschappen of velden van het kenmerk. Raadpleeg de documentatie van het afzonderlijke kenmerk voor informatie over standaardparameterwaarden.
Zie het gedeelte Kenmerken van de C#-taalspecificatievoor meer informatie over toegestane parametertypen.
Doelen voor attributen
Het doel van een kenmerk is de entiteit waarop het kenmerk van toepassing is. Een kenmerk kan bijvoorbeeld van toepassing zijn op een klasse, een bepaalde methode of een hele assembly. Een kenmerk is standaard van toepassing op het element dat hierop volgt. Maar u kunt ook expliciet identificeren of een kenmerk wordt toegepast op een methode, of op de parameter, of op de retourwaarde.
Gebruik de volgende syntaxis om expliciet een kenmerkdoel te identificeren:
[target : attribute-list]
De lijst met mogelijke target
waarden wordt weergegeven in de volgende tabel.
Doelwaarde | Van toepassing op |
---|---|
assembly |
Hele montage |
module |
Huidige assemblagemodule |
field |
Veld in een klasse of een struct |
event |
Gebeurtenis |
method |
Methode ofwel get en set eigenschapstoegangsaccessors |
param |
Methodeparameter(s) of set eigenschapstoegangsparameter(s) |
property |
Eigenschap |
return |
Retourwaarde van een methode, eigenschapsindexeerfunctie of get eigenschapstoegangsfunctie |
type |
Struct, klasse, interface, opsomming of gedelegeerde |
U geeft de field
doelwaarde op om een kenmerk toe te passen op het achterliggende veld dat is gemaakt voor een automatisch geïmplementeerde eigenschap.
In het volgende voorbeeld ziet u hoe u kenmerken toepast op assembly's en modules. Zie Common Attributes (C#)voor meer informatie.
using System;
using System.Reflection;
[assembly: AssemblyTitleAttribute("Production assembly 4")]
[module: CLSCompliant(true)]
In het volgende voorbeeld ziet u hoe u kenmerken toepast op methoden, methodeparameters en waarden voor het retourneren van methoden 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; }
Notitie
Ongeacht de doelen waarop ValidatedContract
is gedefinieerd om geldig te zijn, moet het return
doel worden opgegeven, zelfs als ValidatedContract
zijn gedefinieerd om alleen van toepassing te zijn op retourwaarden. Met andere woorden, de compiler gebruikt geen AttributeUsage
informatie om dubbelzinnige kenmerkdoelen op te lossen. Zie AttributeUsagevoor meer informatie.
Algemene toepassingen voor kenmerken
De volgende lijst bevat enkele veelvoorkomende toepassingen van kenmerken in code:
- Methoden markeren met behulp van het kenmerk
WebMethod
in webservices om aan te geven dat de methode kan worden aangeroepen via het SOAP-protocol. Zie WebMethodAttributevoor meer informatie. - Hoe u de parameters van een methode afstemt voor interoperabiliteit met native code. Zie MarshalAsAttributevoor meer informatie.
- Beschrijving van de COM-eigenschappen voor klassen, methoden en interfaces.
- Niet-beheerde code aanroepen met behulp van de klasse DllImportAttribute.
- Beschrijving van uw assembly in termen van titel, versie, beschrijving of handelsmerk.
- Beschrijven welke leden van een klasse moeten worden geserialiseerd voor persistentie.
- Hoe de relaties te leggen tussen klasse-leden en XML-knooppunten voor XML-serialisatie.
- De beveiligingsvereisten voor methoden beschrijven.
- Kenmerken opgeven die worden gebruikt om beveiliging af te dwingen.
- Optimalisaties beheren door de Just-In-Time-compiler (JIT), zodat de code eenvoudig kan worden opgespoord.
- Informatie verkrijgen over de aanroeper van een methode.
Overzicht van weerspiegeling
Weerspiegeling is handig in de volgende situaties:
- Wanneer u toegang hebt tot kenmerken in de metagegevens van uw programma. Zie Gegevens ophalen die zijn opgeslagen in kenmerkenvoor meer informatie.
- Voor het onderzoeken en instantiëren van types in een assembly.
- Voor het bouwen van nieuwe typen tijdens uitvoeringstijd. Gebruik klassen in System.Reflection.Emit.
- Voor het uitvoeren van late binding hebt u toegang tot methoden voor typen die tijdens runtime zijn gemaakt. Zie het artikel Dynamisch laden en typen gebruiken.
Verwante secties
Voor meer informatie: