• C#特性的介绍及应用场景


    C#特性的介绍及应用场景

    1.特性的任务:特性就是为了支持对象添加一些自我描述的信息,不影响类封装的前提添加额外信息。如果你用这个信息,那特性就有用;如果你不需要这个信息,那么这个特性就没用。

    2.特性的基类:Attribute。例如:Obsolete特性,提出警告信息或错误信息,特性可以影响编译、影响运行。

    3.特性类通常用Attribute结尾,在使用的时候可以用全称,也可以去掉这个结尾,也可以加上小括号显示调用构造函数,如果不加小括号默认调用无参构造函数,也可以在括号内直接给属性或字段赋值。

    4.特性往往只能修饰一个对象一次,需要设置属性的属性的时候,需要给属性添加AttributeUsage属性,可以用来设置:是否允许多次修饰、修饰对象的类别(类or字段等)

    5.DLL文件=IL中间语言+metadata元数据,特性信息会被编译到元数据中。

    6.使用场景

    6.1为类或成员添加描述信息,然后在使用的时候拿到该信息。

         /// <summary>
        /// 描述实体映射的数据表
        /// </summary>
        public class TableNameAttribute : Attribute {
            public TableNameAttribute()
            {
    
            }
            public string TableName { get; set; }
        }
    
        [TableName(TableName = "Users")]
        public class User
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
        
        class Program
        {
            public static void Main(string[] args)
            {
                User user = new User();
                Type t = user.GetType();
                object[] customAttrs = t.GetCustomAttributes(true);
                for (int i = 0; i < customAttrs.Length; i++)
                {
                    if (customAttrs[i] is TableNameAttribute)
                    {
                        TableNameAttribute tnAttr = (TableNameAttribute)customAttrs[i];
                        Console.WriteLine(tnAttr.TableName);
                    }
                }
        }
    }    

    6.2 做数据验证

        public class IntValidateAttribute : Attribute
        {
            /// <summary>
            /// 最小值
            /// </summary>
            private int minValue { get; set; }
            /// <summary>
            /// 最大值
            /// </summary>
            private int maxValue { get; set; }
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="minValue"></param>
            /// <param name="maxValue"></param>
            public IntValidateAttribute(int minValue, int maxValue)
            {
                this.minValue = minValue;
                this.maxValue = maxValue;
            }
            /// <summary>
            /// 检验值是否合法
            /// </summary>
            /// <param name="checkValue"></param>
            /// <returns></returns>
            public bool Validate(int checkValue)
            {
                return checkValue >= minValue && checkValue <= maxValue;
            }
        }
    
         public class User
        {
            [IntValidate(1, 10)]
            public int Id { get; set; }
            public string Name { get; set; }
        }
    
        public class BaseDal
        {
            public static string Insert<T>(T model)
            {
                Type modelType = typeof(T);
                //获取类型的所有属性
                PropertyInfo[] propertyInfos = modelType.GetProperties();
                
                bool boIsCheck = true;
                //循环所有属性
                foreach (var property in propertyInfos){
                    //获取属性的所有特性
                    object[] attrs = property.GetCustomAttributes(true);
                    if (property.PropertyType.Name.ToLower().Contains("int"))
                    {
                        foreach (var attr in attrs)
                        {
                            if (attr is IntValidateAttribute)
                            {
                                IntValidateAttribute intValidate = (IntValidateAttribute)attr;
                                //执行特性的验证逻辑
                                boIsCheck = intValidate.Validate((int)property.GetValue(model));
                            }
                        }
                    }
                    if (!boIsCheck)
                    {
                        break;
                    }
                }
                if (boIsCheck)
                {
                    return "验证通过,插入数据库成功";
                }
                else
                {
                    return "验证失败";
                }
            }
        }
         class Program
        {
            public static void Main(string[] args)
            {
                   string msg = BaseDal.Insert<User>(new User() { Id = 123, Name = "lvcc" });
                Console.WriteLine(msg);
            }
        }            

    6.3 添加说明信息并获取,同6.1

         /// <summary>
        /// 备注特性
        /// </summary>
        public class RemarkAttribute : Attribute
        {
            private string Remark { get; set; }
            public RemarkAttribute(string Remark)
            {
                this.Remark = Remark;
            }
            public string GetRemark()
            {
                return this.Remark;
            }
        }
        
        public enum ESex
        {
            [Attributes.Remark("男的")]
            boy=1
            ,
            [Attributes.Remark("女的")]
            girl =2
        }
    
        /// <summary>
        /// 提供扩展方法
        /// </summary>
        public static class EnumExtension
        {
            public static string GetRemark(this Enum model)
            {
                if (model is ESex)
                {
                    Type type = typeof(ESex);
                    FieldInfo fi = type.GetField(model.ToString());
    
                    object[] attributes = fi.GetCustomAttributes(true);
                    foreach (var attr in attributes)
                    {
                        if (attr is RemarkAttribute)
                        {
                            RemarkAttribute remark = (RemarkAttribute)attr;
                            return remark.GetRemark();
                        }
                    }
                }
               
                return string.Empty;
            }
        }
    
        class Program
        {
            public static void Main(string[] args)
            {
                 Console.WriteLine(ESex.boy.GetRemark());
            }
        }            
  • 相关阅读:
    Spring IoC容器初的初始化过程
    IoC容器初始化过程
    花了一个星期,我终于把RPC框架整明白了!
    RPC简介及框架选择
    ORM框架的前世今生
    什么是索引?Mysql目前主要的几种索引类型
    面试官:谈谈你对Mysql的MVCC的理解?
    sql server 获取数据字段(表的字段和类型信息)
    YAML
    Spring Boot 整合 Mybatis 实现 Druid 多数据源详解
  • 原文地址:https://www.cnblogs.com/grj001/p/12223745.html
Copyright © 2020-2023  润新知