zoukankan      html  css  js  c++  java
  • C#特性

    什么是特性?你每天上班去公司的时候,都要打开门进去公司工作。突然有一天公司倒闭了,公司的门上贴了一个封条,此时我们已经不能进去大门了,就这一个标签贴着我们就真的进不去大门了吗?那肯定不是,只不过这个封条有法律效应,你要是违反了那你就是在和法律作对。那么这个封条标签就类似于特性,它可以让你进入公司之前走一些流程,或者不让你进去公司。

    •  Attribute用来在代码中附加一些元信息,这些元信息可被编译器、.NET Framework、或者我们的程序使用。方法、属性、类等上都可以标注Attribute。
    • 命名一般以Attribute结尾,如果以Attribute结尾的话使用的时候可以省略Attribute。
    • 在Type、MethodInfo、PropertyInfo等上都可以调用object[] GetCustomAttributes(Type attributeType, bool inherit)获取标注的注解对象,因为同一个Attribute可能标注多次,所以返回值是数组。

    例如Obsolete:表示该特性已过时。

     [Obsolete("该类已经过时", true)]
        public class OldClass
        {
            [method: Obsolete("该方法已经过时")]
            public void OldMethod()
            {
                Console.WriteLine("我是一个方法");
            }
        }

    当我们实例化该类的时候,编译器直接告诉我们该类已过时,运行的时候直接报错。

     我们选择Obsolete按F12进去,我们可以看到ObsoleteAttribute继承Attribute,里面有Message和Error属性,再接着就是几个构造函数了。有人就会有疑问了,就这两个东西就能让编译器警告?当然不是了,之所以它能让编译器警告,是因为编译器对它进行了语义分析。那么我可以继承它自己也写一个特性让编译出错吗?你再仔细看下ObsoleteAttribute是不是有一个关键字sealed,这个关键字直接让你无法继承它。那么我们可以继承Attribute,在写下其他特性,就不要纠结这个了。

     

     自定义特性

    //该特性适用于所有的类,而且是非继承的。
        [AttributeUsage(AttributeTargets.Class, Inherited = false)]
        class OldAttribute : Attribute
        {
            private string discretion;
    
            public string Discretion
            {
                get { return discretion; }
                set { discretion = value; }
            }
            public DateTime date;
            public OldAttribute(string discretion)
            {
                this.discretion = discretion;
                date = DateTime.Now;
            }
        }
        [Old("我是一个特性")]
        public class SampleClass
        {
            public SampleClass()
            {
                Console.WriteLine("1111");
            }
        }
     public class NewClass : SampleClass
     {
            public void NewTest()
            {
                Console.WriteLine("222");
            }
     }

    好了写到这里就写完了,是不是就大功告成了呢?当然不是了,想要使用它,我们还必须用反射去获取这个特性里面的属性值。mvc框架里面之所以拿来直接用,那是因为它框架里为你处理了这些过程。

            public static void GetAttributeInfo(Type t)
            {
                //检索自定义属性
                OldAttribute old = (OldAttribute)Attribute.GetCustomAttribute(t, typeof(OldAttribute));
                if (old == null)
                {
                    Console.WriteLine(t.ToString() + "类中自定义特性不存在");
                }
                else
                {
                    Console.WriteLine("特性描述:{0}
    加入事件时间:{1}", old.Discretion, old.date);
                }
            }

    调用:

          static void Main(string[] args)
          {
                GetAttributeInfo(typeof(SampleClass));
                Console.WriteLine("=================");
                GetAttributeInfo(typeof(NewClass));
           }

    结果:

    我们在写一个:

    public class TableNameAttribute : Attribute
        {
            public TableNameAttribute() { }
    
            public string TableName { get; set; }
        }

     然后我们放到创建的User类上:

     [TableName(TableName = "Users")]
        public class User
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }

    调用:

            /// <summary>
            /// 为类或成员添加描述信息,然后在使用的时候拿到该信息。
            /// </summary>
            public static void TableShow()
            {
                Type type = typeof(User);
                object[] obj = type.GetCustomAttributes(true);
                for (int i = 0; i < obj.Length; i++)
                {
                    if (obj[i] is TableNameAttribute)
                    {
                        TableNameAttribute tnAttr = (TableNameAttribute)obj[i];
                        Console.WriteLine(tnAttr.TableName);
                    }
                }
            }

    结果:

    我们再试试下在枚举中使用特性:

     /// <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 Sex
        {
            [Remark("男的")]
            boy = 1,
            [Remark("女的")]
            girl = 2
        }

    调用:

    /// <summary>
        /// 备注属性
        /// </summary>
        public static class EnumExtension
        {
            public static string GetRemake(Enum model)
            {
                if (model is Sex)
                {
                    Type t = typeof(Sex);
                    FieldInfo fi = t.GetField(model.ToString());
                    object[] o = fi.GetCustomAttributes(true);
                    foreach (var attr in o)
                    {
                        if (attr is RemarkAttribute)
                        {
                            RemarkAttribute remark = (RemarkAttribute)attr;
                            return remark.GetRemark();
                        }
                    }
                }
                return string.Empty;
            }
        }
    EnumExtension.GetRemake(Sex.boy)

    我们在看看验证一个类型范围:

     /// <summary>
        /// 验证范围
        /// </summary>
        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 type = typeof(T);
                //反射该类型的所有属性
                PropertyInfo[] infos = type.GetProperties();
                bool boIsCheck = true;
                foreach (var item in infos)
                {
                    //找寻所有的特性的
                    object[] o = item.GetCustomAttributes(true);
                    if (item.PropertyType.Name.ToLower().Contains("int"))
                    {
                        foreach (var attr in o)
                        {
                            IntValidateAttribute intValidate = (IntValidateAttribute)attr;
                            //执行特性的验证逻辑
                            boIsCheck = intValidate.Validate((int)item.GetValue(model));
                        }
                    }
                    if (!boIsCheck)
                    {
                        break;
                    }
                }
                if (boIsCheck)
                {
                    return "验证通过,插入数据库成功";
                }
                else
                {
                    throw new Exception("验证失败");
                }
            }
        }

    调用:

    只要我们这个ID的范围在1-10以内就符合,否则就报错。

    string msg = BaseDal.Insert<User>(new User() { Id = 2, Name = "zero219" });

    结果:

  • 相关阅读:
    Leetcode 148. Sort List
    stat/lstat函数使用
    C/C++内存分配和管理
    initializer_list 列表初始化
    extern "C" 含义
    C语言宏定义##连接符和#符的使用
    rabbitMQ日常管理(转)
    java/rabbitmp发布订阅示例(转)
    oracle分页查询
    oracle imp使用
  • 原文地址:https://www.cnblogs.com/-zzc/p/12984258.html
Copyright © 2011-2022 走看看