特性:用于在运行时传递程序中各种元素(类 方法 结构 枚举 组件)的行为信息的声明性标签 特性用于添加元数据
一、预定义特性 AttributeUsage Conditional Obsolete
[AttributeUsage(validon,AllowMultiple = allowmultiple,Inherited = interited)]
* validon:规定特性可被放置的语言元素 是枚举器AttributeTargets的值的集合 默认值是AttributeTargets.All
* AllowMultiple:可选参数 为特性提供一个布尔值 如果为true 则特性是多用的 默认值是false(单用)
* Inherited:可选参数 为特性提供一个布尔值 如果为true 则该特性可被派生类继承 默认值是false
Conditional 标记了一个条件方法 其执行依赖于指定的预处理标识符 它会引起方法调用的条件编译 取决于指定的值
* [Condition(conditionalSymbol)]
* [Condition("DEBUG")]
Obsolete 标记了不该被使用的程序实体 可以通知编译器丢弃某个特定的目标元素
* [Obsolete(message)]
* [Obsolete(message,iserror)]
* message:一个字符串 描述项目为什么过时的原因以及该替代使用什么
* iserror:是一个布尔值 该值为true时 编译器应该把该项目的使用当作一个错误 默认值是false 编译器生成一个警告
public class Myclass
{
[Conditional("DEBUG")]
public static void Message(string msg)
{
Console.WriteLine(msg);
}
}
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()
{
NewMethod();
}
}
class Test
{
static void function1()
{
Myclass.Message("In Function 1.");
function2();
}
static void function2()
{
Myclass.Message("In Function 2.");
}
public static void Main()
{
Myclass.Message("In Main function.");
function1();
Console.ReadKey();
}
}
二、自定义特性
* 允许创建自定义特性 用于存储声明性的信息 且可在运行时被检索
* 创建步骤:
* 1.声明自定义特性
* 2.构建自定义特性
* 3.在目标程序元素上应用自定义特性
* 4.通过反射访问特性
* 最后一个步骤包含编写一个简单的程序来读取元数据以便查找各种符号
* 元数据是用来描述其他数据的数据和信息 该程序应使用反射来运行时访问特性
*
* 一个新的自定义特性应派生来自System.Attribute 类
* 特性的作用
* 序列化 程序的安全特征 防止即时编译器对代码进行优化从而代码容易调试
* 反射:指的是程序可以访问、检测和修改它本身状态或行为的一种能力
* 程序集包括模块 模块包含类型 类型包含成员 反射则提供了封装程序集、模块和类型的对象
* 可以使用反射动态地创建类型的实例 将类型绑定到现有对象 或从对象中获取类型 然后调用类型的方法访问其字段和属性
//自定义一个新的特性
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
public class DeBugInfo:System.Attribute
{
private int bugNo;
private string developer;
private string lastReview;
public string message;
public DeBugInfo(int bg,string dev,string d)
{
this.bugNo = bg;
this.developer = dev;
this.lastReview = d;
}
public int BugNo
{
get
{
return bugNo;
}
}
public string Developer
{
get
{
return developer;
}
}
public string LastReview
{
get
{
return lastReview;
}
}
public string Message
{
get
{
return message;
}
set
{
message = value;
}
}
}
//实例化自定义
[DeBugInfo(45,"zhang","12/3/2019",Message = "Return type mismatch")]
[DeBugInfo(49, "yin", "12/4/2019", Message = "Return unvalue value")]
class Retangel
{
protected double length;
protected double width;
public Retangel(double l, double w)
{
length = l;
width = w;
}
[DeBugInfo(55,"zhang","19/10/2012",Message = "Return type mismatch")]
public double GetArea()
{
return length * width;
}
[DeBugInfo(56,"yin","19/10/2012")]
public void Display()
{
Console.WriteLine("length:{0}",length);
Console.WriteLine("width:{0}", width);
Console.WriteLine("Area:{0}", GetArea());
}
public static void Main()
{
Retangel rt = new Retangel(10, 20);
rt.Display();
Type type = typeof(Retangel);
//遍历 Retangel 类特性
foreach (Object attributes in type.GetCustomAttributes(false))
{
DeBugInfo dbi = (DeBugInfo)attributes;
if (null != dbi)
{
Console.WriteLine("Bug no: {0}", dbi.BugNo);
Console.WriteLine("Developer: {0}", dbi.Developer);
Console.WriteLine("Last Reviewed: {0}",dbi.LastReview);
Console.WriteLine("Remarks: {0}", dbi.Message);
}
}
//遍历方法特性
}