特性是咸鱼,你不戳它,它不动
.什么是特性
用[]标记,在属性/方法/类的上面标记,如下图
.
.特性有什么用
特性是对所标记的属性/方法/类的补充,但不影响本身的逻辑;特性就像一张标签纸,标签纸贴在物品上,不对物品有任何影响,但是可以通过标签纸查询分类物品;特性在框架中使用非常频繁,如MVC框架中,用[HttpGet]和[HttpPost]特性标记函数是get还是post方法
.特性实战
1.新建特性
特性的核心是一个class,要继承抽象类DemoAttribute,既然特性是类,可以有构造函数和各种方法
/// <summary>
/// 创建一个特性类,必须继承抽象类Attribute
/// 特性名称尽量用Attribute结尾,一种约定,使用时可以省略Attribute
/// </summary>
public class DemoAttribute:Attribute
{
protected int index;
/// <summary>
/// 构造函数,有参数的构造函数,可以没有
/// </summary>
/// <param name="i"></param>
public DemoAttribute(int i) {
index = i;
}
/// <summary>
/// 属性的方法
/// 可以随意设计
/// </summary>
/// <param name="value">接收值</param>
public void show(object value) {
Console.WriteLine($"属性名称{this.GetType().Name},参数{index},接收值{value.ToString()}");
}
}
2.创建测试的model类,当前测试是针对类属性
/// <summary>
/// 测试类
/// </summary>
public class TestModel
{
[Demo(0)]//可以省略attribute,一般省略
public int id { get; set; }
[DemoAttribute(1)]//可以带着attribute
public string name { get; set; }
}
3.调用特性,调用特性有个核心要点特性是咸鱼必须要通过反射手动调用,如果不单独写调用,标记特性没有任何意义;平时代码开发很少用特性,但是框架中会频繁的使用,因为我们平时的逻辑都是基于逻辑本身,很少对逻辑进行额外的标记扩展
下面是第一种调用方法
/// <summary>
/// 具体执行过程如何使用特性
/// </summary>
public class TestExecute
{
/// <summary>
/// 直接使用特性方式
/// </summary>
/// <param name="model"></param>
public void Execute(TestModel model) {
//反射的方式,遍历整个类
foreach (PropertyInfo item in typeof(TestModel).GetProperties())
{
//判断当前属性是否有特性
if (item.IsDefined(typeof(DemoAttribute),true))
{
//获取特性
DemoAttribute demoAttribute= (DemoAttribute)item.GetCustomAttribute(typeof(DemoAttribute), true);
//执行特性
demoAttribute.show(item.GetValue(model).ToString());
}
}
}
}
具体调用
TestModel testModel = new TestModel()
{
id = 123,
name = "测试"
};
new TestExecute().Execute(testModel);
执行结果
下面是第二种调用方案,在第一种的基础上加入[扩展]的语法,使调用更简单
/// <summary>
/// 用扩展的方式
/// </summary>
/// <param name="model"></param>
public static void ExtendTest(this TestModel model) {
//反射的方式,遍历整个类
foreach (PropertyInfo item in typeof(TestModel).GetProperties())
{
//判断当前属性是否有特性
if (item.IsDefined(typeof(DemoAttribute), true))
{
//获取特性
DemoAttribute demoAttribute = (DemoAttribute)item.GetCustomAttribute(typeof(DemoAttribute), true);
//执行特性
demoAttribute.show(item.GetValue(model).ToString());
}
}
}
具体调用
TestModel testModel = new TestModel()
{
id = 123,
name = "测试"
};
testModel.ExtendTest();
Console.ReadKey();
执行结果和第一种一样