使用反射、特性简化代码

参考项目:利用反射验证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 <= )
{
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 == && 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是获取不到的。

最新文章

  1. .NET WEB项目的调试发布相关
  2. 在IIS8.5的环境下配置WCF的Restful Service
  3. java条件语句练习题
  4. C#组合查询小Demo
  5. 【FOL】第九周
  6. UNICODE字符集(20140520)
  7. photoshop:css3插件
  8. MySQL基础之第8章 视图
  9. 第二百四十九天 how can I 坚持
  10. hdu4111 Alice and Bob
  11. HibernateTemplate类的方法flush()
  12. LAMP介绍及安装
  13. 2016-3-6.16:43------------js开始
  14. cpptoolstip界面提示库使用
  15. vim + DoxygenToolkit.vim环境搭建
  16. 【模板小程序】求第n个质数
  17. IntelliJ IDEA的main方法,for循环,syso的快捷键
  18. &#39;webpack-dev-server&#39; 不是内部或外部命令,也不是可运行的程序
  19. python call so
  20. 跟踪分析Linux内核的启动过程小解

热门文章

  1. [IOI2018]机械娃娃——线段树+构造
  2. BZOJ2877 NOI2012魔幻棋盘(二维线段树)
  3. jquery 循环绑定click的问题
  4. Python中csv模块解析
  5. Codeforces Round #505 Div. 1 + Div. 2
  6. 【XSY2731】Div 数论 杜教筛 莫比乌斯反演
  7. 板载 SPI-FLASH 的烧写方法
  8. Vagrant 遇到的问题
  9. Docker自动补全容器名
  10. poj3179 Corral the Cows