カスタム属性の取得は簡単なプロセスです。 まず、取得する属性のインスタンスを宣言します。 次に、Attribute.GetCustomAttribute メソッドを使用して、取得する属性の値に新しい属性を初期化します。 新しい属性が初期化されたら、そのプロパティを使用して値を取得できます。
重要
この記事では、実行コンテキストに読み込まれたコードの属性を取得する方法について説明します。 リフレクションのみのコンテキストに読み込まれたコードの属性を取得するには、「方法: アセンブリを Reflection-Only CustomAttributeDataに示すように、 クラスを使用する必要があります。
このセクションでは、属性を取得する次の方法について説明します。
属性の単一インスタンスの取得
次の例では、(前のセクションで説明した) DeveloperAttribute がクラス レベルの MainApp クラスに適用されます。
GetAttribute メソッドは、GetCustomAttribute を使用して、クラス レベルで DeveloperAttribute に格納されている値を取得してから、コンソールに表示します。
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
上記のプログラムを実行すると、次のテキストが表示されます。
The Name Attribute is: Joan Smith.
The Level Attribute is: 42.
The Reviewed Attribute is: True.
属性が見つからない場合、GetCustomAttribute メソッドは null 値に MyAttribute を初期化します。 次の使用例は、このようなインスタンスの MyAttribute をチェックし、属性が見つからない場合にユーザーに通知します。 クラス スコープに DeveloperAttribute が見つからない場合は、コンソールに次のメッセージが表示されます。
The attribute was not found.
前の例では、属性定義が現在の名前空間にあることを前提としています。 属性定義が現在の名前空間に存在しない場合は、必ずその名前空間をインポートしてください。
同じスコープに適用された属性の複数のインスタンスの取得
前の例では、検査するクラスと検索する特定の属性が GetCustomAttribute メソッドに渡されます。 クラス レベルで属性のインスタンスが 1 つだけ適用されている場合、そのコードは適切に機能します。 ただし、1 つの属性の複数のインスタンスが同じクラス レベルで適用されている場合、GetCustomAttribute メソッドはすべての情報を取得しません。 同じ属性の複数のインスタンスが同じスコープに適用されている場合は、Attribute.GetCustomAttributes メソッドを使用して、属性のすべてのインスタンスを配列に配置できます。 たとえば、DeveloperAttribute の 2 つのインスタンスが同じクラスのクラス レベルに適用されている場合、GetAttribute メソッドを変更して、両方の属性で見つかった情報を表示できます。 同じレベルで複数の属性を適用することを忘れないでください。 属性は、AllowMultiple クラスで true に設定された AttributeUsageAttribute プロパティで定義する必要があります。
次のコード例は、GetCustomAttributes メソッドを使用して、任意のクラスの DeveloperAttribute のすべてのインスタンスを参照する配列を作成する方法を示しています。 次に、すべての属性の値がコンソールに出力されます。
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
属性が見つからない場合、このコードはユーザーに警告します。 それ以外の場合は、DeveloperAttribute の両方のインスタンスに含まれる情報が表示されます。
異なるスコープに適用された属性の複数のインスタンスの取得
GetCustomAttributes メソッドと GetCustomAttribute メソッドは、クラス全体を検索せず、そのクラス内の属性のすべてのインスタンスを返します。 代わりに、指定されたメソッドまたはメンバーを一度に 1 つだけ検索します。 すべてのメンバーに同じ属性が適用されているクラスがあり、それらのメンバーに適用されているすべての属性の値を取得する場合は、すべてのメソッドまたはメンバーを個別に GetCustomAttributes および GetCustomAttributeに指定する必要があります。
次のコード例では、クラスをパラメーターとして受け取り、クラス レベルとそのクラスのすべての個々のメソッドで DeveloperAttribute (以前に定義) を検索します。
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
メソッド レベルまたはクラス レベルで DeveloperAttribute のインスタンスが見つからない場合、GetAttribute メソッドは、属性が見つからなかったことをユーザーに通知し、属性を含まないメソッドまたはクラスの名前を表示します。 属性が見つかった場合、コンソールには Name、Level、および Reviewed フィールドが表示されます。
Type クラスのメンバーを使用して、渡されたクラスの個々のメソッドとメンバーを取得できます。 この例では、最初に Type オブジェクトに対してクエリを実行して、クラス レベルの属性情報を取得します。 次に、Type.GetMethods を使用して、すべてのメソッドのインスタンスを System.Reflection.MemberInfo オブジェクトの配列に配置し、メソッド レベルの属性情報を取得します。 また、Type.GetProperties メソッドを使用してプロパティ レベルの属性をチェックしたり、コンストラクター レベルの属性をチェックする Type.GetConstructors を使用することもできます。
クラス メンバーからの属性の取得
属性は、クラス レベルで取得するだけでなく、メソッド、プロパティ、フィールドなどの個々のメンバーにも適用できます。
GetCustomAttribute メソッドと GetCustomAttributes メソッドを使用して、これらの属性を取得できます。
例
次の例では、メソッドに適用された属性を取得する方法を示します。
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.");
}
}
}
関連項目
.NET