1 什么是特性
特性是一种允许我们向程序的程序集添加元数据的语言结构,它用于保存程序结构信息的某种特殊类型的类。
2 预定义的特性
2.1 Obsolete
public ObsoleteAttribute(string? message, bool error);
public ObsoleteAttribute(string? message);
第一个参数表示错误信息,第二个参数表示是否报错。
class Program
{
[Obsolete("this method is expired")]
static void Foo()
{
}
static void Main(string[] args)
{
Foo();
}
}
2.2 Conditional
public ConditionalAttribute(string conditionString);
指示编译器,如果定义了conditionString编译符号,就和普通函数方法没有区别,否则忽略代码中方法的的所有调用。
#define test
using System;
using System.Diagnostics;
class Program
{
[Conditional("test")]
static void Foo()
{
Console.WriteLine("i am Foo");
}
static void Main(string[] args)
{
Foo();
}
}
2.3 调用者信息特性
调用者信息特性可以访问文件路径、代码行数、调用成员的名称等源代码信息,这三个特性的名称分别为CallerFilePath、CallerLineNumber和CallerMemberName,这些方法只能用于方法中的可选参数。
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
class Program
{
static void Foo(string str,
[CallerFilePath] string filePath = "",
[CallerLineNumber] int num = 0,
[CallerMemberName] string name = "")
{
Console.WriteLine(str);
Console.WriteLine("filePath {0}", filePath);
Console.WriteLine("Line {0}", num);
Console.WriteLine("Call from {0}", name);
}
static void Main(string[] args)
{
Foo("hahaha");
}
}
3 自定义特性
3.1 自定义特性
体上声明特性和声明其他类是一样的,只是所有的特性都派生自System.Attribute。根据惯例,特性名使用Pascal命名法并且以Attribute后缀结尾,当为目标应用特性时,我们可以不使用后缀。如:对于SerializableAttribute
和MyAttributeAttribute这两个特性,我们在把它应用到结构的时候可以使用[Serializable和MyAttribute短名
public class MyAttributeAttribute : System.Attribute
{
public string Description;
public string ver;
public string Reviwer;
public MyAttributeAttribute(string desc, string ver, string Rev) //构造函数
{
Description = desc;
this.ver = ver;
Reviwer = Rev;
}
}
3.2 限制特性的使用
有一个很重要的预定义特性AttributeUsage可以运用到自定义特性上,我们可以用它来限制特性使用在某个目标类型上
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, //必须的,指示MyAttribute只能应用到类和方法上
Inherited = false, //可选,表明不能被派生类继承
AllowMultiple = false)] //可选,表明不能有MyAttribute的多个实例应用到同一个目标上
public class MyAttributeAttribute : System.Attribute
{
public string Description;
public string ver;
public string Reviwer;
public MyAttributeAttribute(string desc, string ver, string Rev) //构造函数
{
Description = desc;
this.ver = ver;
Reviwer = Rev;
}
}
3.3 访问特性
对于自定义的特性,我们可以用Type中的IsDefined和GetCustomAttributes方法来获取,这里就不举例来。关于反射和Type,可以参考C#反射(reflection)_目标:MVP-CSDN博客