可以定义自定义属性并将其放入源代码,但如果没有某种方式检索这些信息并对其加以利用,那么这些属性的价值就会很小。 通过使用反射,可以检索使用自定义属性定义的信息。 键方法是 GetCustomAttributes,它返回一个对象数组,这些对象是源代码属性的运行时等效项。 此方法有许多重载版本。 有关详细信息,请参阅 Attribute。
属性规范,例如:
[Author("P. Ackerman", Version = 1.1)]
class SampleClass { }
在概念上等效于以下代码:
var anonymousAuthorObject = new Author("P. Ackerman")
{
Version = 1.1
};
但是,代码不会执行,直到查询SampleClass的属性。 调用GetCustomAttributes在SampleClass上会导致构造和初始化Author对象。 如果类具有其他属性,则以类似的方式构造其他属性对象。 GetCustomAttributes 然后返回 Author 数组中的对象和任何其他属性对象。 然后,可以循环访问此数组,根据每个数组元素的类型确定应用了哪些属性,并从属性对象中提取信息。
下面是一个完整的示例。 定义自定义属性、应用于多个实体,并通过反射进行检索。
// Multiuse attribute.
[System.AttributeUsage(System.AttributeTargets.Class |
System.AttributeTargets.Struct,
AllowMultiple = true) // Multiuse attribute.
]
public class AuthorAttribute : System.Attribute
{
string Name;
public string Version;
public AuthorAttribute(string name)
{
Name = name;
// Default value.
Version = "1.0";
}
public string GetName() => Name;
}
// Class with the Author attribute.
[Author("P. Ackerman")]
public class FirstClass
{
// ...
}
// Class without the Author attribute.
public class SecondClass
{
// ...
}
// Class with multiple Author attributes.
[Author("P. Ackerman"), Author("R. Koch", Version = "2.0")]
public class ThirdClass
{
// ...
}
class TestAuthorAttribute
{
public static void Test()
{
PrintAuthorInfo(typeof(FirstClass));
PrintAuthorInfo(typeof(SecondClass));
PrintAuthorInfo(typeof(ThirdClass));
}
private static void PrintAuthorInfo(System.Type t)
{
System.Console.WriteLine($"Author information for {t}");
// Using reflection.
System.Attribute[] attrs = System.Attribute.GetCustomAttributes(t); // Reflection.
// Displaying output.
foreach (System.Attribute attr in attrs)
{
if (attr is AuthorAttribute a)
{
System.Console.WriteLine($" {a.GetName()}, version {a.Version}");
}
}
}
}
/* Output:
Author information for FirstClass
P. Ackerman, version 1.0
Author information for SecondClass
Author information for ThirdClass
R. Koch, version 2.0
P. Ackerman, version 1.0
*/