zoukankan      html  css  js  c++  java
  • .NET技术-1.0.使用反射、特性简化代码(验证Model类)

    使用反射、特性简化代码 

    参考项目:利用反射验证Model类/AssemblyVerification

    假设现在有一个学生类(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 class RegexStudent
        {
            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 Require: Attribute
        {
            private bool isRequire;//必填
    
            public bool IsRequire
            {
                get { return isRequire; }
            }
    
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="isRequire">是否必填</param>
            public Require(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(true)]
            public string Address { get; set; }
    
            /// <summary>
            /// 性别
            /// </summary>
            [Require(true)]
            public string Sex;
        }

     通过特性检查类的属性:

        public class RegexStudent
        { 
            public static string CheckRequire<T>(T instance)
            {
                StringBuilder validateMsg = new StringBuilder();
    
                Type t = typeof(T);
    
                var propertyInfos = t.GetProperties();
                //有人会发现,Sex也标记了[Require(true)],为什么没有验证信息,
                //这是因为,Sex没有实现属性{ get; set; },GetProperties是获取不到的。
    
                foreach (var propertyInfo in propertyInfos)
                {
                    Require require = (Require)Attribute.GetCustomAttribute(propertyInfo, typeof(Require));
                    
                    //没标记,直接跳过
                    if (require == null)
                    {
                        continue;
                    }
    
                    //获取属性的数据类型
                    var type = propertyInfo.PropertyType.ToString().ToLower();
    
                    //获取该属性的值
                    var value = propertyInfo.GetValue(instance, null);
    
                    switch (type)
                    {
                        case "system.string":
                            {
                                if (string.IsNullOrEmpty((string)value) && require.IsRequire)
                                {
                                    validateMsg.Append(propertyInfo.Name).Append("不能为空").Append(",");
                                }
                            }
                            break;
    
                        case "system.int":
                        case "system.int32":
                        case "system.int64":
                            {
                                if ((int)value == 0 && require.IsRequire)
                                {
                                    validateMsg.Append(propertyInfo.Name).Append("必须大于0").Append(",");
                                }
                            }
                            break;
                    }
                }
    
                return validateMsg.ToString().TrimEnd(',');
            }
        }

    执行验证:

            protected void Page_Load(object sender, EventArgs e)
            {
                Student student = new Student();
    
                student.Name = "张三";
    
                string strMsg = RegexStudent.CheckRequire<Student>(student);
    
                Response.Write(strMsg);
            }

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

  • 相关阅读:
    分布式进程
    T1008 选数 codevs
    P1364 医院设置 洛谷
    T1046 旅行家的预算 codevs
    T1164 统计数字 codevs
    codevs——T1860 最大数||洛谷——P1107 最大整数
    手动脱Mole Box V2.6.5壳实战
    手动脱FSG壳实战
    手动脱NsPacK壳实战
    手动脱UPX 壳实战
  • 原文地址:https://www.cnblogs.com/1285026182YUAN/p/5169283.html
Copyright © 2011-2022 走看看