zoukankan      html  css  js  c++  java
  • 使用反射、特性简化代码

    假设现在有一个学生类(Student)

        /// <summary>
        /// 学生类
        /// </summary>
        public class Student
        {   
            /// <summary>
            /// 名字
            /// </summary>
            private string name;
            public string Name
            {
                get { return name; }
                set { name = value; }
            }
    
            /// <summary>
            /// 年龄
            /// </summary>
            public int Age { get; set; }
    
            /// <summary>
            /// 地址
            /// </summary>
            public string Address { get; set; }
    
            /// <summary>
            /// 性别
            /// </summary>
            public string Sex;
        }

    如果需要判断某些字段(属性)是否为空,是否大于0,便有以下代码:

            public static string ValidateStudent(Student student)
            {
                StringBuilder validateMessage = new StringBuilder();
                if (string.IsNullOrEmpty(student.Name))
                {
                    validateMessage.Append("名字不能为空");
                }
    
                if (string.IsNullOrEmpty(student.Sex))
                {
                    validateMessage.Append("性别不能为空");
                }
    
                if (student.Age <= 0)
                {
                    validateMessage.Append("年龄必填大于0");
                }
    
                //...... 几百行
    
                // 写到这里发现不对啊,如果必填项有20多个,难道我要一直这样写吗!
                return validateMessage.ToString();
            }

    这样的代码,重用性不高,而且效率低。

    我们可以用特性,反射,然后遍历属性并检查特性。

    首先自定义一个【必填】特性类,继承自Attribute

        /// <summary>
        /// 【必填】特性,继承自Attribute
        /// </summary>
        public sealed class RequireAttribute : Attribute
        {
            private bool isRequire;
            public bool IsRequire
            {
                get { return isRequire; }
            }
    
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="isRequire"></param>
            public RequireAttribute(bool isRequire)
            {
                this.isRequire = isRequire;
            }
        }

    然后用这个自定义的特性标记学生类的成员属性:

        /// <summary>
        /// 学生类
        /// </summary>
        public class Student
        {   
            /// <summary>
            /// 名字
            /// </summary>
            private string name;
            [Require(true)]
            public string Name
            {
                get { return name; }
                set { name = value; }
            }
    
            /// <summary>
            /// 年龄
            /// </summary>
            [Require(true)]
            public int Age { get; set; }
    
            /// <summary>
            /// 地址
            /// </summary>
            [Require(false)]
            public string Address { get; set; }
    
            /// <summary>
            /// 性别
            /// </summary>
            [Require(true)] 
            public string Sex;
        }

    通过特性检查类的属性:

            /// <summary>
            /// 检查方法,支持泛型
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="instance"></param>
            /// <returns></returns>
            public static string CheckRequire<T>(T instance)
            {
                var validateMsg = new StringBuilder();
    
                //获取T类的属性
                Type t = typeof (T);
                var propertyInfos = t.GetProperties();
    
                //遍历属性
                foreach (var propertyInfo in propertyInfos)
                {
                    //检查属性是否标记了特性
                    RequireAttribute attribute = (RequireAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof (RequireAttribute));
    
                    //没标记,直接跳过
                    if (attribute == null)
                    {
                        continue;
                    }
    
                    //获取属性的数据类型
                    var type = propertyInfo.PropertyType.ToString().ToLower();
    
                    //获取该属性的值
                    var value = propertyInfo.GetValue(instance);
    
                    if (type.Contains("system.string"))
                    {
                        if (string.IsNullOrEmpty((string) value) && attribute.IsRequire)
                            validateMsg.Append(propertyInfo.Name).Append("不能为空").Append(",");
                    }
                    else if (type.Contains("system.int"))
                    {
                        if ((int) value == 0 && attribute.IsRequire)
                            validateMsg.Append(propertyInfo.Name).Append("必须大于0").Append(",");
                    }
                }
    
                return validateMsg.ToString();
            }

    执行验证:

            static void Main(string[] args)
            {
                var obj = new Student()
                {
                    Name = ""
                };
                Console.WriteLine(CheckRequire(obj));
                Console.Read();
            }

    结果输出:

    有人会发现,Sex也标记了[Require(true)],为什么没有验证信息,这是因为,Sex没有实现属性{ get; set; },GetProperties是获取不到的。

  • 相关阅读:
    c#基础语言编程-装箱和拆箱
    c#基础语言编程-集合
    c#基础语言编程-异常处理
    HDU 5038 Grade北京赛区网赛1005
    新建Oracle数据库时,提示使用database control配置数据库时,要求在当前oracle主目录中配置监听程序
    Android开发学习笔记--计时器的应用实例
    Android开发学习笔记--一个有界面A+B的计算器
    Android开发学习笔记--给一个按钮定义事件
    HDU 5014 Number Sequence(位运算)
    HDU 5007 Post Robot KMP (ICPC西安赛区网络预选赛 1001)
  • 原文地址:https://www.cnblogs.com/zhuyongblogs/p/5169054.html
Copyright © 2011-2022 走看看