Attribute
Attribute,作为名词,意思是标注,特征的意思。我们经常在日常编码中遇到,在某些类,方法,字段,属性上面有如下情形:
[AttributeTargets_All]
public TestAttributeClass()
{
}
[Obsolete("该方法已经停用!请使用Method2")]
public void Method1()
{
}
即以一个中括号包含进来的一些特殊的注解属性,来修饰类,方法,字段,属性。这些属性可以是.net自带的,也可以是用户自定义出来的。
借鉴MSDN的解释:
“公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型、字段、方法和属性等。Attributes和Microsoft .NET Framework文件的元数据保存在一起,可以用来向运行时描述你的代码,或者在程序运行的时候影响应用程序的行为。”
下面以一个简单的示例,介绍一下Attribute的用法:
首先,自定义一些标注属性:
//AttributeTargets指定对哪些程序元素使用(如这里是针对类)
[AttributeUsage(AttributeTargets.Class)]
public class AttributeTargets_ClassAttribute : Attribute
{
}
//限制用在方法上面
[AttributeUsage(AttributeTargets.Method)]
public class AttributeTargets_MethodAttribute : Attribute
{
public AttributeTargets_MethodAttribute(string ctorStr)
{
this.testProperty = ctorStr;
}
public string testProperty { get; set; }
}
//限制用在方法和类上面
[AttributeUsage(AttributeTargets.Method|AttributeTargets.Class)]
public class AttributeTargets_MethodOrClassAttribute : Attribute
{
}
//所有元素上都可以使用
[AttributeUsage(AttributeTargets.All)]
public class AttributeTargets_AllAttribute : Attribute
{
}
创建一个测试类:
[AttributeTargets_Class]
[AttributeTargets_MethodOrClass]
[AttributeTargets_All]
class TestAttributeClass
{
[AttributeTargets_All]
public TestAttributeClass()
{
}
[Obsolete("该方法已经停用!请使用Method2")]
public void Method1()
{
}
[AttributeTargets_Method("just for testing!")]
public void Method2()
{
}
[AttributeTargets_MethodOrClass]
public void Method3()
{
}
[AttributeTargets_All]
public string MyProperty1 { get; set; }
[AttributeTargets_All]
public string MyProperty2 { get; set; }
[AttributeTargets_All]
public int MyFiled1 = 0;
[AttributeTargets_All]
public string MyFiled2 = "test";
}
static void Main(string[] args)
{
Type classType = typeof(TestAttributeClass);
Console.WriteLine("下面是获得所有包含attribute的属性:");
foreach (PropertyInfo pro in classType.GetProperties())
{
foreach (Attribute attr in Attribute.GetCustomAttributes(pro))
{
Console.WriteLine("Property:{0} have attribute:{1}", pro.Name, attr.ToString());
}
Console.WriteLine("---------------------------");
}
Console.WriteLine("下面获得是所有包含attribute的字段:");
foreach (FieldInfo field in classType.GetFields())
{
foreach (Attribute attr in Attribute.GetCustomAttributes(field))
{
Console.WriteLine("Field:{0} have attribute:{1}", field.Name, attr.ToString());
}
Console.WriteLine("---------------------------");
}
Console.WriteLine("下面是获得所有包含AttributeTargets_MethodAttribute注解属性的方法及attribute中的属性值:");
foreach (MethodInfo method in classType.GetMethods())
{
foreach (Attribute attr in Attribute.GetCustomAttributes(method))
{
//Console.WriteLine("Method:{0} have attribute:{1}",method.Name,attr.ToString());
if (attr.GetType() == typeof(AttributeTargets_MethodAttribute))
{
//Console.WriteLine("Method:{0} have attribute:{1}", method.Name, attr.ToString());
Console.WriteLine("Method:{0} have attribute:{1}", method.Name, ((AttributeTargets_MethodAttribute)attr).testProperty);
}
}
Console.WriteLine("---------------------------");
}
Console.WriteLine("下面是获得Method1中ObsoleteAttribute注解属性的只读属性Message:");
ObsoleteAttribute obs =
(ObsoleteAttribute)Attribute.GetCustomAttribute(classType.GetMethod("Method1"), typeof(ObsoleteAttribute));
Console.WriteLine("Method1 have attribute message:{0}",obs.Message);
}
编译运行,结果是:
实际上,获得注解属性主要通过.net的反射,Visual Studio中的Intelligence Edit也是通过反射来出提示的。
以上,关于attribute就记录到此。