Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Het ophalen van een aangepast kenmerk is een eenvoudig proces. Declareer eerst een exemplaar van het kenmerk dat u wilt ophalen. Gebruik vervolgens de methode Attribute.GetCustomAttribute om het nieuwe kenmerk te initialiseren naar de waarde van het kenmerk dat u wilt ophalen. Zodra het nieuwe kenmerk is geïnitialiseerd, kunt u de eigenschappen ervan gebruiken om de waarden op te halen.
Belangrijk
In dit artikel wordt beschreven hoe u kenmerken ophaalt voor code die in de uitvoeringscontext is geladen. Als u kenmerken wilt ophalen voor code die is geladen in de context met alleen weerspiegeling, moet u de CustomAttributeData klasse gebruiken, zoals wordt weergegeven in Procedure: Assembly's laden in de Reflection-Only Context.
In deze sectie worden de volgende manieren beschreven om kenmerken op te halen:
Meerdere exemplaren van een kenmerk ophalen die zijn toegepast op hetzelfde bereik
Het ophalen van meerdere exemplaren van een kenmerk die zijn toegepast op verschillende contexten
Eén exemplaar van een kenmerk ophalen
In het volgende voorbeeld wordt de DeveloperAttribute (beschreven in de vorige sectie) toegepast op de MainApp class op klasseniveau. De methode GetAttribute gebruikt GetCustomAttribute om de waarden op te halen die zijn opgeslagen in DeveloperAttribute op klasseniveau voordat deze worden weergegeven in de console.
using System;
using System.Reflection;
using CustomCodeAttributes;
[Developer("Joan Smith", "42", Reviewed = true)]
class MainApp
{
public static void Main()
{
// Call function to get and display the attribute.
GetAttribute(typeof(MainApp));
}
public static void GetAttribute(Type t)
{
// Get instance of the attribute.
DeveloperAttribute MyAttribute =
(DeveloperAttribute) Attribute.GetCustomAttribute(t, typeof (DeveloperAttribute));
if (MyAttribute == null)
{
Console.WriteLine("The attribute was not found.");
}
else
{
// Get the Name value.
Console.WriteLine($"The Name Attribute is: {MyAttribute.Name}.");
// Get the Level value.
Console.WriteLine($"The Level Attribute is: {MyAttribute.Level}.");
// Get the Reviewed value.
Console.WriteLine($"The Reviewed Attribute is: {MyAttribute.Reviewed}.");
}
}
}
Imports System.Reflection
Imports CustomCodeAttributes
<Developer("Joan Smith", "42", Reviewed:=True)>
Class MainApp
Public Shared Sub Main()
' Call function to get and display the attribute.
GetAttribute(GetType(MainApp))
End Sub
Public Shared Sub GetAttribute(t As Type)
' Get instance of the attribute.
Dim MyAttribute As DeveloperAttribute =
CType(Attribute.GetCustomAttribute(t, GetType(DeveloperAttribute)), DeveloperAttribute)
If MyAttribute Is Nothing Then
Console.WriteLine("The attribute was not found.")
Else
' Get the Name value.
Console.WriteLine("The Name Attribute is: {0}.", MyAttribute.Name)
' Get the Level value.
Console.WriteLine("The Level Attribute is: {0}.", MyAttribute.Level)
' Get the Reviewed value.
Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttribute.Reviewed)
End If
End Sub
End Class
De uitvoering van het voorgaande programma geeft de volgende tekst weer:
The Name Attribute is: Joan Smith.
The Level Attribute is: 42.
The Reviewed Attribute is: True.
Als het kenmerk niet wordt gevonden, initialiseert de GetCustomAttribute methode MyAttribute naar een null-waarde. In dit voorbeeld wordt MyAttribute gecontroleerd op een dergelijk geval en wordt de gebruiker op de hoogte gesteld als het kenmerk niet wordt gevonden. Als DeveloperAttribute niet wordt gevonden in het klassebereik, wordt in de console het volgende bericht weergegeven:
The attribute was not found.
In het voorgaande voorbeeld wordt ervan uitgegaan dat de kenmerkdefinitie zich in de huidige naamruimte bevindt. Vergeet niet om de naamruimte te importeren waarin de kenmerkdefinitie zich bevindt als deze zich niet in de huidige naamruimte bevindt.
Meerdere exemplaren van een kenmerk ophalen dat is toegepast op hetzelfde bereik
In het voorgaande voorbeeld worden de klasse die moet worden gecontroleerd en het specifieke kenmerk dat moet worden gevonden, doorgegeven aan de GetCustomAttribute methode. Deze code werkt goed als er slechts één exemplaar van een kenmerk wordt toegepast op klasseniveau. Als echter meerdere exemplaren van een kenmerk op hetzelfde klasseniveau worden toegepast, haalt de GetCustomAttribute methode niet alle informatie op. In gevallen waarin meerdere exemplaren van hetzelfde kenmerk worden toegepast op hetzelfde bereik, kunt u Attribute.GetCustomAttributes methode gebruiken om alle exemplaren van een kenmerk in een matrix te plaatsen. Als bijvoorbeeld twee exemplaren van DeveloperAttribute worden toegepast op het klasseniveau van dezelfde klasse, kan de methode GetAttribute worden gewijzigd om de informatie in beide kenmerken weer te geven. Vergeet niet om meerdere kenmerken op hetzelfde niveau toe te passen. Het kenmerk moet worden gedefinieerd met de eigenschap AllowMultiple ingesteld op true in de klasse AttributeUsageAttribute.
In het volgende codevoorbeeld ziet u hoe u de GetCustomAttributes methode gebruikt om een matrix te maken die verwijst naar alle exemplaren van DeveloperAttribute in een bepaalde klasse. De code voert vervolgens de waarden uit van alle kenmerken naar de console.
public static void GetAttribute(Type t)
{
DeveloperAttribute[] MyAttributes =
(DeveloperAttribute[]) Attribute.GetCustomAttributes(t, typeof (DeveloperAttribute));
if (MyAttributes.Length == 0)
{
Console.WriteLine("The attribute was not found.");
}
else
{
for (int i = 0 ; i < MyAttributes.Length ; i++)
{
// Get the Name value.
Console.WriteLine($"The Name Attribute is: {MyAttributes[i].Name}.");
// Get the Level value.
Console.WriteLine($"The Level Attribute is: {MyAttributes[i].Level}.");
// Get the Reviewed value.
Console.WriteLine($"The Reviewed Attribute is: {MyAttributes[i].Reviewed}.");
}
}
}
Public Shared Sub GetAttribute(t As Type)
Dim MyAttributes() As DeveloperAttribute =
CType(Attribute.GetCustomAttributes(t, GetType(DeveloperAttribute)), DeveloperAttribute())
If MyAttributes.Length = 0 Then
Console.WriteLine("The attribute was not found.")
Else
For i As Integer = 0 To MyAttributes.Length - 1
' Get the Name value.
Console.WriteLine("The Name Attribute is: {0}.", MyAttributes(i).Name)
' Get the Level value.
Console.WriteLine("The Level Attribute is: {0}.", MyAttributes(i).Level)
' Get the Reviewed value.
Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttributes(i).Reviewed)
Next i
End If
End Sub
Als er geen kenmerken worden gevonden, waarschuwt deze code de gebruiker. Anders wordt de informatie in beide gevallen van DeveloperAttribute weergegeven.
Meerdere exemplaren ophalen van een attribuut dat is toegepast op verschillende scopen
Met de methoden GetCustomAttributes en GetCustomAttribute wordt niet in een hele klasse gezocht en worden alle exemplaren van een kenmerk in die klasse geretourneerd. In plaats daarvan doorzoeken ze slechts één opgegeven methode of lid tegelijk. Als u een klasse hebt waarop hetzelfde kenmerk is toegepast op elk lid en u de waarden wilt ophalen in alle kenmerken die op die leden zijn toegepast, moet u elke methode of elk lid afzonderlijk opgeven voor GetCustomAttributes en GetCustomAttribute.
In het volgende codevoorbeeld wordt een klasse als parameter gebruikt en wordt gezocht naar de DeveloperAttribute (eerder gedefinieerd) op klasseniveau en op elke afzonderlijke methode van die klasse:
public static void GetAttribute(Type t)
{
DeveloperAttribute att;
// Get the class-level attributes.
// Put the instance of the attribute on the class level in the att object.
att = (DeveloperAttribute) Attribute.GetCustomAttribute (t, typeof (DeveloperAttribute));
if (att == null)
{
Console.WriteLine($"No attribute in class {t.ToString()}.\n");
}
else
{
Console.WriteLine($"The Name Attribute on the class level is: {att.Name}.");
Console.WriteLine($"The Level Attribute on the class level is: {att.Level}.");
Console.WriteLine($"The Reviewed Attribute on the class level is: {att.Reviewed}.\n");
}
// Get the method-level attributes.
// Get all methods in this class, and put them
// in an array of System.Reflection.MemberInfo objects.
MemberInfo[] MyMemberInfo = t.GetMethods();
// Loop through all methods in this class that are in the
// MyMemberInfo array.
for (int i = 0; i < MyMemberInfo.Length; i++)
{
att = (DeveloperAttribute) Attribute.GetCustomAttribute(MyMemberInfo[i], typeof (DeveloperAttribute));
if (att == null)
{
Console.WriteLine($"No attribute in member function {MyMemberInfo[i].ToString()}.\n");
}
else
{
Console.WriteLine($"The Name Attribute for the {MyMemberInfo[i].ToString()} member is: {att.Name}.");
Console.WriteLine($"The Level Attribute for the {MyMemberInfo[i].ToString()} member is: {att.Level}.");
Console.WriteLine($"The Reviewed Attribute for the {MyMemberInfo[i].ToString()} member is: {att.Reviewed}.\n");
}
}
}
Public Shared Sub GetAttribute(t As Type)
Dim att As DeveloperAttribute
' Get the class-level attributes.
' Put the instance of the attribute on the class level in the att object.
att = CType(Attribute.GetCustomAttribute(t, GetType(DeveloperAttribute)), DeveloperAttribute)
If att Is Nothing
Console.WriteLine("No attribute in class {0}.\n", t.ToString())
Else
Console.WriteLine("The Name Attribute on the class level is: {0}.", att.Name)
Console.WriteLine("The Level Attribute on the class level is: {0}.", att.Level)
Console.WriteLine("The Reviewed Attribute on the class level is: {0}.\n", att.Reviewed)
End If
' Get the method-level attributes.
' Get all methods in this class, and put them
' in an array of System.Reflection.MemberInfo objects.
Dim MyMemberInfo() As MemberInfo = t.GetMethods()
' Loop through all methods in this class that are in the
' MyMemberInfo array.
For i As Integer = 0 To MyMemberInfo.Length - 1
att = CType(Attribute.GetCustomAttribute(MyMemberInfo(i), _
GetType(DeveloperAttribute)), DeveloperAttribute)
If att Is Nothing Then
Console.WriteLine("No attribute in member function {0}.\n", MyMemberInfo(i).ToString())
Else
Console.WriteLine("The Name Attribute for the {0} member is: {1}.",
MyMemberInfo(i).ToString(), att.Name)
Console.WriteLine("The Level Attribute for the {0} member is: {1}.",
MyMemberInfo(i).ToString(), att.Level)
Console.WriteLine("The Reviewed Attribute for the {0} member is: {1}.\n",
MyMemberInfo(i).ToString(), att.Reviewed)
End If
Next
End Sub
Als er geen exemplaren van de DeveloperAttribute worden gevonden op methodeniveau of klasseniveau, geeft de GetAttribute methode de gebruiker een bericht dat er geen kenmerken zijn gevonden en wordt de naam weergegeven van de methode of klasse die het kenmerk niet bevat. Als er een kenmerk wordt gevonden, worden in de console de velden Name, Levelen Reviewed weergegeven.
U kunt de leden van de Type-klasse gebruiken om de afzonderlijke methoden en leden in de doorgegeven klasse op te halen. In dit voorbeeld wordt eerst een query uitgevoerd op het Type-object om kenmerkgegevens op te halen voor het klasseniveau. Vervolgens wordt Type.GetMethods gebruikt om exemplaren van alle methoden in een matrix van System.Reflection.MemberInfo objecten te plaatsen om kenmerkgegevens voor het methodeniveau op te halen. U kunt ook de methode Type.GetProperties gebruiken om te controleren op kenmerken op het eigenschapsniveau of Type.GetConstructors om te controleren op kenmerken op het constructorniveau.
Kenmerken ophalen van klasseleden
Naast het ophalen van kenmerken op klasseniveau, kunnen kenmerken ook worden toegepast op afzonderlijke leden, zoals methoden, eigenschappen en velden. De methoden GetCustomAttribute en GetCustomAttributes kunnen worden gebruikt om deze kenmerken op te halen.
Voorbeeld
In het volgende voorbeeld ziet u hoe u een kenmerk ophaalt dat is toegepast op een methode:
using System;
using System.Reflection;
[AttributeUsage(AttributeTargets.Method)]
public class MyAttribute : Attribute
{
public string Description { get; }
public MyAttribute(string description) { Description = description; }
}
public class MyClass
{
[MyAttribute("This is a sample method.")]
public void MyMethod() { }
}
class AttributeRetrieval
{
public static void Main()
{
// Create an instance of MyClass
MyClass myClass = new MyClass();
// Retrieve the method information for MyMethod
MethodInfo methodInfo = typeof(MyClass).GetMethod("MyMethod");
MyAttribute attribute = (MyAttribute)Attribute.GetCustomAttribute(methodInfo, typeof(MyAttribute));
if (attribute != null)
{
// Print the description of the method attribute
Console.WriteLine($"Method Attribute: {attribute.Description}");
}
else
{
Console.WriteLine("Attribute not found.");
}
}
}