Attribute特性
特性是用于在运行时传递程序中各种元素行为信息的声明性标签加粗样式 ,一个声明标签是通过放置在它所应用的元素前的方括号[]来描述。
在.Net框架里提供了两种类型的特性:
- 预定义特性
- 自定义特性
预定义特性
- AttributeUsage: 用于描述如何使用一个自定义特性;
[AttributeUsage(AttributeTargets.Class,AllowMultiple =true,Inherited =true)]
AttributeTargets——选择被指定使用的某种元素(默认all全部)
AllowMultiple——bool类型的特性属性,true为多用,false为单用
Inherited——bool类型的特性属性,true为可被派生类继承,false为不可
- Conditional:标记一个指定的预处理标识符
[Conditional("DEBUG")]
常用的conditionSymbol有“DEBUG”和“Trace”
- Obsolete:标记不应被使用的程序实体
[Obsolete("Dont't use OldMethod,use NewMethod instead",true)]
自定义特性
.Net框架允许创建自定义特性,用于存储声明性的信息,且可以在运行时被检索。
- 声明自定义特性
- 构建自定义特性
- 应用自定义特性
- 利用反射访问特性
例子:
构建自定义特性
//创建一个存储一个属性和一个方法的特性
[AttributeUsage(AttributeTargets.Class,AllowMultiple =true,Inherited =true)]
//特性必须继承Attribute类
public class DescriptionAttribute:Attribute
{
public DescriptionAttribute()
{
Console.WriteLine($"{nameof(DescriptionAttribute)}被构造");
}
public string Description { get; set; }
public void show()
{
Console.WriteLine(nameof(DescriptionAttribute));
Console.WriteLine(this.Description);
}
}
应用自定义特性
[Description(Description ="这是普通学生")]
public class NormalStudent:Student
{
public override void Study()
{
Console.WriteLine("普通学生上课");
}
}
利用反射访问特性
//用于获取student类中的特性,得到DA后执行show方法
public static void ManageStudent<S>(S student)where S : Student
{
Console.WriteLine($"{student.Id}_{student.Name }");
student.Study();
//反射
Type type = student.GetType();
if (type.IsDefined(typeof(DescriptionAttribute), true))
{
DescriptionAttribute DA= (DescriptionAttribute)type.GetCustomAttribute(typeof(DescriptionAttribute), true);
DA.show();
}
}
**记录一个通过反射+泛型进行类型转换的写法
public static void Main(string[] args)
{
NormalStudent normal = new NormalStudent()
{
Id = 123,
Name = "lok",
Age = 19
};
Worker worker = Trans<NormalStudent, Worker>(normal);
}
private static TOut Trans<TIn, TOut>(TIn tIn)
{
Type typeIn = typeof(TIn);
Type typeOut = typeof(TOut);
TOut tOut = (TOut)Activator.CreateInstance(typeOut);
foreach (var item in typeOut.GetProperties())
{
PropertyInfo info = typeIn.GetProperty(item.Name);
object typeOutValue = info.GetValue(tIn);
item.SetValue(tOut, typeOutValue);
}
return tOut;
}
NormalStudent 和 Worker 是两个具有相同属性的类