特性初体验

特性是咸鱼,你不戳它,它不动

.什么是特性

用[]标记,在属性/方法/类的上面标记,如下图

.

.特性有什么用

特性是对所标记的属性/方法/类的补充,但不影响本身的逻辑;特性就像一张标签纸,标签纸贴在物品上,不对物品有任何影响,但是可以通过标签纸查询分类物品;特性在框架中使用非常频繁,如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();

        执行结果和第一种一样

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值