A.定义
官方解释:特性是给指定的某一声明的一则附加的声明性信息。 允许类似关键字的描述声明。它对程序中的元素进行标注,如类型、字段、方法、属性等。从.net角度看,特性是一种 类,这些类继承于System.Attribute类,用于对类、属性、方法、事件等进行描述,主要用在反射中。但从面向对象的级别看,其实Attribute是类型级别的,而不是对象级别。
B.作为编译器的指令
Conditional:起条件编译的作用,只有满足条件,才允许编译器对它的代码进行编译。一般在程序调试的时候使用。
DllImport:用来标记费.net的函数,表明该方法在一个外部的DLL中定义。
Obsolete:这个属性用来标记当前的方法已经废弃,不再使用。
注:Attribute是一个类,因此DllImport也是一个类,Attribute类是在编译的时候实例化,而不是像通常那样在运行时实例化。
CLSCompliant:保证整个程序集代码遵守CLS,否则编译将报错。
C.自定义特性
[AttributeUsageAttribute(AttributeTargets.All //可以应用到任何元素,默认为AttributeTargets.All
, AllowMultiple = true //允许应用多次,该特性能否被重复放在同一个元素前多次,默认为false
, Inherited = false //该特性不继承到派生,默认为false
)]
public class MyselfAttribute : System.Attribute{} //特性也是一个类,必须继承于System.Attribute类,命名规范为“类名”+Attribute。不管是直接还是间接继承,都会成为一个特性类,特性类的声明定义了一种可以放置在声明之上新的特性。
D.实例1
#define DEBUG
using System.Runtime.InteropServices.DllImportAttribute
using System.Runtime.InteropServices.DllImport
namespace ConsoleTest
{
class Program
{
[System.Diagnostics.DebuggerStepThrough] //跳过调试
[Conditional("DEBUG")] //只有在DEBUG模式或定义#define DEBUG时,才会被执行
public static void Message(string msg)
{
Console.WriteLine(msg);
object[] MyAttrs = typeof(Program).GetCustomAttributes(typeof(MyAttr), false); //通过反射获取特性
}
static void Main(string[] args)
{
Message("...");
}
}
}
E.实例2
1.创建自己的属性
//AttributeUsage:用来定义属性用在什么地方.
//AllowMultiple:定义用户是否能给元素添加一个或多个相同的属性
//BindingFlags:一个枚举.这里是用来限制返回成员类型的
using System;
using System.Reflection;
namespace AttributeDemo
{
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Property |
AttributeTargets.Method |
AttributeTargets.Constructor,
AllowMultiple = true)]
public class BugFixAttribute : Attribute //定制一个BugFixAttribute属性类
{
public BugFixAttribute(string bugNumber, string comments)
{
BugNumber = bugNumber;
Comments = comments;
}
public readonly string BugNumber;
public readonly string Comments;
public string Author = null;
public override string ToString() //重写ToString()方法
{
if (null == Author)
return string.Format("BugFix {0} : {1}", BugNumber, Comments);
else
return string.Format("BugFix {0} by {1} : {2}", BugNumber, Author, Comments);
}
public static void DisplayFixes(System.Type t) //静态方法DisplayFix
{
object[] fixes = t.GetCustomAttributes(typeof(BugFixAttribute), false);//反射t中的BugFix属性
Console.WriteLine("Displaying fixes for {0}", t);
foreach (BugFixAttribute bugFix in fixes)
{
Console.WriteLine(" {0}", bugFix);
}
foreach (MemberInfo member in t.GetMembers(BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.Static)) //迭代类上的所有成员,并用BindingFlags枚举限制返回成员列表
{
// ICustomAttributeProvider表示所有可以承载“CustomAttribute”自定义属性的载体,可以是类、方法、属性、字段等等
// MemberInfo:ICustomAttributeProvider,其中ICustomAttributeProvider包含GetCustomAttributes方法
object[] memberFixes = member.GetCustomAttributes(typeof(BugFixAttribute), false);
if (memberFixes.Length > 0) //如果Bugfix属性数目大于0
{
Console.WriteLine(" {0}", member.Name); //输出这些成员
foreach (BugFixAttribute memberFix in memberFixes)
{
Console.WriteLine(" {0}", memberFix);
}
}
}
}
}
}
2.BugFix属性的使用
using System;
namespace AttributeDemo
{
[BugFix("101", "Created some methods")]
public class MyBuggyCode //MyBuggyCode类
{
[BugFix("90125", "Removed call to base()", Author = "Morgan")]
public MyBuggyCode()
{
}
[BugFix("2112", "Returned a non null string")]
[BugFix("38382", "Returned OK")]
public string DoSomething()
{
return "OK";
}
}
}
3.最后通过调用DisplayFixes方法对附加了属性的对象进行操作
static void Main(string[] args)
{
BugFixAttribute.DisplayFixes(typeof(MyBuggyCode));
Console.ReadKey();
}
15、全局变量
只是对某一进程的不同模块而言是共享的,不同进程间需要使用进程间通信才能实现数据交互
∴多个不同进程内的全局变量是不共享的。