1.C# 特性(Attribute)
特性,是用来给代码添加额外信息的一种手段,我们通常是将特性标记到方法,类或者属性上,在使用的这些结构的时候,通过反射(reflection)这一非常高级的技术,获取它们通过特性标记的信息(在编译好的程序集中,作为元数据),从而进行某些特殊的处理。
.Net 框架提供了两种类型的特性:预定义特性和自定义特性。
1.1 规定特性(Attribute)
规定特性(Attribute)的语法如下:
[attribute(positional_parameters, name_parameter = value, ...)]
element
使用:
特性的使用很简单,在结构声明的上一行,用"[]"扩起特性类名即可:
系统也给我们提供了一些特性,比如Serializable 标记一个可序列化的类,DebuggerStepThrough设置方法在调试时为跳过的状态。
[Serializable]
class Sunshine{...}
它其实是省略了(),如果使用特性的其它的构造方法,显示声明即可:
[Serializable("test")]
class Sunshine{...}
1.2 预定义特性(Attribute)
.Net 框架提供了三种预定义特性:
- AttributeUsage
- Conditional
- Obsolete
1.2.1 AttributeUsage(自定义特性)
预定义特性 AttributeUsage 描述了如何使用一个自定义特性类。它规定了特性可应用到的项目的类型。
规定该特性的语法如下:
[AttributeUsage(
validon,
AllowMultiple=allowmultiple,
Inherited=inherited
)]
其中:
- 参数 validon 规定特性可被放置的语言元素。它是枚举器 AttributeTargets 的值的组合。默认值是 AttributeTargets.All。
- 参数 allowmultiple(可选的)为该特性的 AllowMultiple 属性(property)提供一个布尔值。如果为 true,则该特性是多用的。默认值是 false(单用的)。
- 参数 inherited(可选的)为该特性的 Inherited 属性(property)提供一个布尔值。如果为 true,则该特性可被派生类继承。默认值是 false(不被继承)。
例如:
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
使用:
- 构建一个自定义特性[AttributeUsage()]
- 编写一个自定义特性类,类名必须以Attribute结尾并继承自Attribute类
- 将定位的参数通过构造函数传递(每个自定义特性类必须至少有一个构造函数)
- 通过反射检索到特性信息
using System;
class MainClass
{
public static void Main()
{
Maoxiandao test = new Maoxiandao();
Type t = test.GetType();
object[] o = t.GetCustomAttributes(true);
TestAttribute attribute = (TestAttribute)o[0];
Console.WriteLine(attribute.msg);
}
}
[Test("这是测试类")] //这里的Test对应下方的TestAttribute
public class Maoxiandao { }
[AttributeUsage(AttributeTargets.All)]
public class TestAttribute : Attribute
{
public string msg;
public TestAttribute(string msg)
{
this.msg = msg;
}
}
1.2.2 Conditional
可以为一个方法添加Conditional特性使这个方法的执行依赖于指定的预处理标识符
规定该特性的语法如下:
[Conditional(
conditionalSymbol
)]
使用案例:
#define Debug //有这个就打印两个,没这个就打印一个
using System;
using System.Diagnostics;
class MainClass
{
public static void Main()
{
Fun1();
Fun2();
}
[Conditional("Debug")]
public static void Fun1()
{
Console.WriteLine("Fun1");
}
public static void Fun2()
{
Console.WriteLine("Fun2");
}
}
1.2.3 Obsolete
可以为类、属性、字段、方法添加Obsolete特性使这个目标元素标记为过时的
Obsolete特性的第二个参数是否为error默认为false,不影响编译通过只会提示warning,如果为true则编译不会通过
规定该特性的语法如下:
[Obsolete(
message
)]
[Obsolete(
message,
iserror
)]
- 参数 message,是一个字符串,描述项目为什么过时以及该替代使用什么。
- 参数 iserror,是一个布尔值。如果该值为 true,编译器应把该项目的使用当作一个错误。默认值是 false(编译器生成一个警告)。
using System;
public class MyClass
{
[Obsolete("Don't use OldMethod, use NewMethod instead", true)]
static void OldMethod()
{
Console.WriteLine("It is the old method");
}
static void NewMethod()
{
Console.WriteLine("It is the new method");
}
public static void Main()
{
OldMethod();
}
}
当您尝试编译该程序时,编译器会给出一个错误消息说明:
Don't use OldMethod, use NewMethod instead