Hämtar information som lagras i attribut
Att hämta ett anpassat attribut är en enkel process. Deklarera först en instans av attributet som du vill hämta. Använd sedan metoden Attribute.GetCustomAttribute för att initiera det nya attributet till värdet för det attribut som du vill hämta. När det nya attributet har initierats kan du använda dess egenskaper för att hämta värdena.
Viktig
Den här artikeln beskriver hur du hämtar attribut för kod som läses in i exekveringskontexten. För att hämta attribut för kod som lästs in i endast reflektionskontext måste du använda klassen CustomAttributeData, enligt instruktionerna i Hur du: Läser in assemblyn i Reflection-Only-context.
I det här avsnittet beskrivs följande sätt att hämta attribut:
Hämtar flera instanser av ett attribut som tillämpas på samma omfång
Hämtar flera instanser av ett attribut som tillämpas på olika omfång
Hämtar en enskild instans av ett attribut
I följande exempel tillämpas DeveloperAttribute
(som beskrivs i föregående avsnitt) på klassen MainApp
på klassnivå. Metoden GetAttribute
använder GetCustomAttribute
för att hämta de värden som lagras i DeveloperAttribute
på klassnivå innan de visas i konsolen.
using namespace System;
using namespace System::Reflection;
using namespace CustomCodeAttributes;
[Developer("Joan Smith", "42", Reviewed = true)]
ref class MainApp
{
public:
static void Main()
{
// Call function to get and display the attribute.
GetAttribute(MainApp::typeid);
}
static void GetAttribute(Type^ t)
{
// Get instance of the attribute.
DeveloperAttribute^ MyAttribute =
(DeveloperAttribute^) Attribute::GetCustomAttribute(t, DeveloperAttribute::typeid);
if (MyAttribute == nullptr)
{
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);
}
}
};
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: {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);
}
}
}
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
Körningen av föregående program visar följande text:
The Name Attribute is: Joan Smith.
The Level Attribute is: 42.
The Reviewed Attribute is: True.
Om attributet inte hittas initierar metoden GetCustomAttribute
MyAttribute
till ett null-värde. Det här exemplet kontrollerar MyAttribute
för en sådan instans och meddelar användaren om attributet inte hittas. Om DeveloperAttribute
inte hittas i klassomfånget visas följande meddelande i konsolen:
The attribute was not found.
I föregående exempel förutsätts att attributdefinitionen finns i det aktuella namnområdet. Kom ihåg att importera namnområdet där attributdefinitionen finns om den inte finns i det aktuella namnområdet.
Hämta flera instanser av ett attribut som tillämpas på samma omfång
I föregående exempel skickas klassen som ska inspekteras och det specifika attribut som ska hittas till metoden GetCustomAttribute. Koden fungerar bra om endast en instans av ett attribut tillämpas på klassnivå. Men om flera instanser av ett attribut tillämpas på samma klassnivå hämtar metoden GetCustomAttribute
inte all information. Om flera instanser av samma attribut tillämpas på samma omfång kan du använda Attribute.GetCustomAttributes metod för att placera alla instanser av ett attribut i en matris. Om till exempel två instanser av DeveloperAttribute
tillämpas på klassnivån för samma klass kan GetAttribute
-metoden ändras för att visa informationen som finns i båda attributen. Kom ihåg att tillämpa flera attribut på samma nivå. Attributet måste definieras med egenskapen AllowMultiple
inställd på true
i klassen AttributeUsageAttribute.
I följande kodexempel visas hur du använder metoden GetCustomAttributes
för att skapa en matris som refererar till alla instanser av DeveloperAttribute
i en viss klass. Koden matar sedan ut värdena för alla attribut till konsolen.
public:
static void GetAttribute(Type^ t)
{
array<DeveloperAttribute^>^ MyAttributes =
(array<DeveloperAttribute^>^) Attribute::GetCustomAttributes(t, DeveloperAttribute::typeid);
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: {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);
}
}
}
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: {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);
}
}
}
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
Om inga attribut hittas varnar den här koden användaren. Annars visas informationen i båda instanserna av DeveloperAttribute
.
Hämta flera instanser av ett attribut som tillämpas på olika omfång
Metoderna GetCustomAttributes och GetCustomAttribute söker inte i en hel klass och returnerar alla instanser av ett attribut i den klassen. I stället söker de bara efter en angiven metod eller medlem i taget. Om du har en klass med samma attribut som tillämpas på varje medlem och du vill hämta värdena i alla attribut som tillämpas på dessa medlemmar, måste du ange varje metod eller medlem individuellt till GetCustomAttributes
och GetCustomAttribute
.
Följande kodexempel tar en klass som en parameter och söker efter DeveloperAttribute
(definierades tidigare) på klassnivå och på varje enskild metod i den klassen:
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, DeveloperAttribute::typeid);
if (att == nullptr)
{
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);
}
// Get the method-level attributes.
// Get all methods in this class, and put them
// in an array of System.Reflection.MemberInfo objects.
array<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], DeveloperAttribute::typeid);
if (att == nullptr)
{
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);
}
}
}
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 {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);
}
// 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 {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);
}
}
}
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
Om inga instanser av DeveloperAttribute
hittas på metodnivå eller klassnivå meddelar GetAttribute
-metoden användaren att inga attribut hittades och visar namnet på den metod eller klass som inte innehåller attributet. Om ett attribut hittas visar konsolen fälten Name
, Level
och Reviewed
.
Du kan använda medlemmarna i klassen Type för att hämta de enskilda metoderna och medlemmarna i den överförda klassen. Det här exemplet frågar först Type
-objektet för att hämta attributinformation för klassnivån. Därefter används Type.GetMethods för att placera instanser av alla metoder i en matris med System.Reflection.MemberInfo objekt för att hämta attributinformation för metodnivån. Du kan också använda metoden Type.GetProperties för att söka efter attribut på egenskapsnivå eller Type.GetConstructors för att söka efter attribut på konstruktornivå.
Hämta attribut från klassmedlemmar
Förutom att hämta attribut på klassnivå kan attribut även tillämpas på enskilda medlemmar, till exempel metoder, egenskaper och fält. Metoderna GetCustomAttribute
och GetCustomAttributes
kan användas för att hämta dessa attribut.
Exempel
I följande exempel visas hur du hämtar ett attribut som tillämpas på en metod:
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: {0}", attribute.Description);
}
else
{
Console.WriteLine("Attribute not found.");
}
}
}