使用反射、特性简化代码

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

.NET技术-1.0.使用反射、特性简化代码(验证Model类)的更多相关文章

  1. 创建JDBC模板简化代码、JDBC应用的事务管理以及连接池的作用

    一.创建JDBC模板简化代码 一个简单的查询.要做这么一大堆事情,并且还要处理异常,我们不防来梳理一下: 1.获取connection  2.获取statement  3.获取resultset  4 ...

  2. .Net Core3.0 WEB API 中使用FluentValidation验证,实现批量注入

    为什么要使用FluentValidation 1.在日常的开发中,需要验证参数的合理性,不紧前端需要验证传毒的参数,后端也需要验证参数 2.在领域模型中也应该验证,做好防御性的编程是一种好的习惯(其实 ...

  3. C# 6.0语法新特性体验(二)

    之前我在文章通过Roslyn体验C# 6.0的新语法中介绍了一些C# 6.0的语法特性,现在随着Visual Studio 14 CTP3的发布,又陆续可以体验一些新的特性了,这里简单的介绍一下之前没 ...

  4. LINQ体验(2)——C# 3.0新语言特性和改进(上篇)

    整体来说.Visual Studio 2008和.NET 3.5是建立在.NET2.0核心的基础之上,.NET2.0核心本身将不再变化(假设不了解.NET2.0的朋友,请參看MSDN或者一些经典的书籍 ...

  5. C# 3.0新语言特性和改进(一)

    引言 关于C#3.0的特性,园子里已经有了一大把,可能大家都很熟悉了,虽然本人开发中使用过,但自己还是需要记录一下,总结一下.同时也是后面写Linq知识的基础.希望有兴趣的朋友,可以看看. C# 3. ...

  6. C#7.0中有新特性

    以下将是 C# 7.0 中所有计划的语言特性的描述.随着 Visual Studio “15” Preview 4 版本的发布,这些特性中的大部分将活跃起来.现在是时候来展示这些特性,你也告诉借此告诉 ...

  7. paip.php 5.0 5.3 5.4 5.5 -6.0的新特性总结与比较

    paip.php 5.0 5.3 5.4  5.5 -6.0的新特性总结与比较 PHP5的新特性 2 · 对象的参照过渡是默认的(default) 3 · 引入访问属性的限制 3 · 引入访问方法的限 ...

  8. C# 6.0 的新特性

    1. 自动的属性初始化器Auto Property initialzier 之前的方式: public class AutoPropertyBeforeCsharp6 { private string ...

  9. Atitit jquery  1.4--v1.11  v1.12  v2.0  3.0 的新特性

    Atitit jquery  1.4--v1.11  v1.12  v2.0  3.0 的新特性 1.1. Jquery1.12  jQuery 2.2 和 1.12 新版本发布 - OPEN资讯.h ...

随机推荐

  1. docker registry v2与harbor的搭建

    docker的仓库 1 registry的安装 docker的仓库我们可以使用docker自带的registry,安装起来很简单,但是可能有点使用起来不是很方便.没有图形化. 开始安装 使用镜像加速器 ...

  2. HDU4341-Gold miner-分组DP

    模拟黄金矿工这个游戏,给出每一个金子的位置和所需时间,计算在给定时间内最大收益. 刚看这道题以为金子的位置没什么用,直接DP就行,WA了一发终于明白如果金子和人共线的话只能按顺序抓. 这就是需要考虑先 ...

  3. [PA2012] Tax

    传送门:>Here< 题意:给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是 ...

  4. Alice's Chance POJ - 1698(按时间点建边)

    Alice's Chance Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7791   Accepted: 3174 De ...

  5. luogu P3128 [USACO15DEC]最大流Max Flow (树上差分)

    题目描述 Farmer John has installed a new system of N-1N−1 pipes to transport milk between the NN stalls ...

  6. MT【305】丹德林双球

    如图.在正方体$ABCD-A_1B_1C_1D_1$中,点$M,N$分别是直线$CD,AB$上的动点,点$P$是$\Delta A_1C_1D_1$内的动点(不包括边界),记直线$DP$与$MN$所成 ...

  7. 【cf849D】Rooter's Song(思维)

    D. Rooter's Song 题意 x轴.y轴上有n个人,第i个人\(g_i==1\)则坐标为\((p_i,0)\)否则\((0,p_i)\),\(t_i\)秒后垂直所在坐标轴出发,到达边界x=w ...

  8. JumpServer 跳板机系统

    Jumpserver项目为开源项目,截至到目前最新版本为4.0,4.0功能并不完整,无上传.下载功能,配置复杂.启动服务也较繁琐,推荐使用0.3.2版本,文档较全,安装简单文档链接https://gi ...

  9. bzoj4671: 异或图

    bzoj4671: 异或图 Description 定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与 G2 中的出现次数之和为 1, 那么边 ( ...

  10. 【BZOJ2576】[JSOI2011]序的计数 (动态规划)

    [BZOJ2576][JSOI2011]序的计数 (动态规划) 题面 BZOJ 题解 首先构建一个新的虚拟节点连接所有目标节点,强行将其作为第一个被访问的节点,这样子就解决了图不连通的问题. 除了目标 ...