使用反射、特性简化代码

参考项目:利用反射验证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. Appium-desktop安装启用Inspector一直报错An unknown server-side error occurred...

    遇到的问题是: 启用Appium-desktop的Inspector一直报错:An unknown server-side error occurred while processing the co ...

  2. django 报错 : django.core.exceptions.ImproperlyConfigured: The STATICFILES_DIRS setting should not contain the STATIC_ROOT setting

    错误原因有可能是在settings中静态文件目录设置的有问题 STATIC_ROOT=os.path.join(BASE_DIR,"static/")#错误 STATIC_ROOT ...

  3. virtualenv virtualenvwrapper 虚拟环境创建

    虚拟环境创建 安装 C:\Users\Python> pip install virtualenv Requirement already satisfied: virtualenv ) C:\ ...

  4. jQuery 方式模拟提交表单

    //add test moudle define(function(require , exports , module) { //=========== 不使用模块化只使用如下代码即可 start ...

  5. project 2013 删除资源

    1.分析 在资源名称这边一旦输入过资源名称,下次点击下拉框就会出现历史记录,如何删除 2.步骤 资源-->分配资源-->点击资源名称,按F2,按DEL键

  6. STL之set和map

    by attack666      set与map   map 内部实现是一棵红黑树 定义 key和value分别对应着两种类型 map<key, value> mp; 内部函数 直观的理 ...

  7. luogu3242 接水果 (整体二分+树状数组)

    考虑整体二分,问题就变成了每个(水果)路径有多少个满足条件(权值)的(盘子)子路径 考虑一个盘子(a,b)表示两端点(不妨设dfn[a]<dfn[b]),那么他能接到的水果(u,v)一定满足(不 ...

  8. css 禁止选中文本

    css 如何禁止选中文字 .noselect { -webkit-touch-callout: none; /* iOS Safari */ -webkit-user-select: none; /* ...

  9. java 不定长参数

    一,不定长参数的规定 一个方法只能有一个不定长参数,并且这个不定长参数必须是该方法的最后一个参数. 示例: public class VariArgs { public static void mai ...

  10. 【SPOJ10707】COT2 - Count on a tree II

    题目大意:给定一棵 N 个节点的无根树,每个节点有一个颜色.现有 M 个询问,每次询问一条树链上的不同颜色数. 题解:学会了树上莫队. 树上莫队是将节点按照欧拉序进行排序,将树上问题转化成序列上的问题 ...