using System;
//属性的作用:
//1.对程序代码进行说明
//2.指示C#编译器
// 1)如何检测: [Assembly:CLSCompliant(true)]
// 2)如何编译:
//3.指示CLR
// 1)如何检测:
// 2)如何编译:[DebuggableAttribute]
//4.程序:利用反射,决定其逻辑分枝。
//代码属性是对代码实体(属性目标)的描述说明。代码属性能在程序的设计时<由编译器将C#源程序编译成IL中间代码>
//或运行时<在运行时通过查询代码属性,从而动态显示代码属性或动态地改变代码的执行方式>发挥作用。
//代码属性是从System.Attribute派生的一个属性类的实例。
//为了保持与“公共语言规范”(CLS)相容,属性类必须直接或间接地从公共抽象类System.Attribute派生,C#只允许符合CLS规范的属性。
//System.Object-->System.Attribute-->自定义属性类XXXAttribute。
//属性类应该只提供一个公共构造器,它接受属性类的强制性(或定位性)状态信息;
//而且属性类可以提供公共字段/properties接受属性类的可选(或命名)状态信息; 属性类不应提供任何的公共方法、事件或其它成员。
//属性类名有一个Attribute后缀,这是为了保持与标准的相容性,但不是必须的。
//第二步:应用属性:将属性与代码实体关联。
//在C#中,需要把代码属性放到属性目标之前的一对方括号中,允许指定一个前缀来明确代码属性要应用于的属性目标<代码实体>
//[(代码实体显示说明符:)代码属性]
//代码实体
//如果属性类的构造器不获取参数,圆括号可有可无。
//可将多个属性应用于单个属性目标时,属性的循序是无关紧要的。
//以下代码具有相同的功能
//[Seraalizable][Flags]
//[Seraalizable,Flags]
//[FlagsAttribute,SeraalizableAttribute]
//[FlagsAttribute(),SeraalizableAttribute()]
//应用一个属性时,必须传递编译时的常量表达式。
//C#编译器在查找类名的时候,先寻找XXX属性类名,如果找不到,则去寻找XXXAttribute属性类名。
//(C#编译器允许省略Attribute的后缀以减少代码的录入量,并增加源代码的可读性)
//由编译器将源程序编译成中间代码时,程序中的代码属性信息将存储在.Net程序集的元数据当中生成额外的附加信息,
//这就适得Attribute具有了描述程序代码本身的能力。
//可以在运行时查询这种可扩展的元数据信息,以便能正确使用和运行程序。
//大多数属性对编译器来说没有意义,编译器只是在源代码中检测到属性,然后机械地生成对应的元数据,
//但是编译器内建了对某些属性的支持,这些属性指示编译器如何进行编译。
//编译器检测到向一个应用一个自定义属性时:编译器在元数据中动态生成创建属性类的一个实例所需要的信息。
//1.编译器调用属性类的构造器,向它传递指定的任何定位参数,从而构造属性类的确一个实例
//2.编译器会根据采用的增强型语法,来指定的任何命令参数,对任何的公共字段和property进行初始化
//3.编译器会将属性对象的状态序列化成一个字节流,住留在目标元素的元数据表记录项中,
// 在运行时,可以对元数据中包含的字节流进行反序列化,从而构造出类的一个实例。
// 序列化的一个字节流中:
// 定位参数:一字节长度的类型ID 数据值 一字节长度ID的类型 数据值 一字节长度ID的类型 数据值
// 命令参数:字段/property名称 一字节长度的类型ID 数据值 字段/property名称 一字节长度的类型ID 数据值
// 字段/property名称 一字节长度的类型ID 数据值
//
[assembly: MyAttr(1)] // Applied to assembly
[module: MyAttr(2)] // Applied to module
//必须显示指定属性目标
[type: MyAttr(3)] // Applied to type
// default:type
internal sealed class SomeType
{
[field: MyAttr(5)] // Applied to field
// default:field
public Int32 SomeField = 0;
[return: MyAttr(6)] // Applied to return value
[method: MyAttr(7)] // Applied to method
// default:method
public Int32 SomeMethod(
[param: MyAttr(8)] // Applied to parameter
// default:param
Int32 SomeParam) { return SomeParam; }
[property: MyAttr(9)] // Applied to property
// default:property
public String SomeProp
{
[method: MyAttr(10)] // Applied to get accessor method
// default:method
get { return null; }
}
[event: MyAttr(11)] // Applied to event
[field: MyAttr(12)] // Applied to compiler-generated field
[method: MyAttr(13)] // Applied to compiler-generated add & remove methods
// default:event
public event EventHandler SomeEvent;
[type:MyAttr(14)] // Applied to delegate
[return: MyAttr(15)] // Applied to return
// default:type
public delegate int MyDelegate(int a);
public void Main()
{
System.Type t = typeof(int);
}
}
[AttributeUsage(AttributeTargets.All)]
public class MyAttr : Attribute
{
public MyAttr(Int32 x) { }
}