Util应用程序框架公共操作类(一):数据类型转换公共操作类(介绍篇)
本系列文章将介绍一些对初学者有帮助的辅助类,这些辅助类本身并没有什么稀奇之处,如何能发现需要封装它们可能更加重要,所谓授之以鱼不如授之以渔,掌握封装公共操作类的技巧才是关键,我会详细说明创建这些类的动机和思考过程,以帮助初学者发现和封装自己需要的东西。创建公共操作类的技巧,大家可以参考我的这篇文章——应用程序框架实战十二:公共操作类开发技巧(初学者必读)。
封装公共操作类,不仅要把技术上困难的封装进来,还需要不断观察自己的代码,以找出哪些部分可以更加简化。本文将介绍一个容易被大家所忽视的东西——数据类型转换。
数据类型转换可以把某个源类型转换为目标类型,比如把字符串转换为整型。一种选择是,你可以使用System.Convert类进行转换。
string input = "";
int result = System.Convert.ToInt32( input);
这样看起来好像没什么问题,不过input很明显不一定是个常量,如果你还在使用ASP.NET Web Form这样的技术,你需要在后置代码中从控件读取值。
string input = TextBox1.Text;
int result = System.Convert.ToInt32( input);
当客户输入整数时,不会有什么问题,但他如果输入一个字母或汉字,上面代码会抛出一个异常,“System.FormatException: 输入字符串的格式不正确。”,这可能不是你想要的。当然,你可以在客户端进行JS验证,不过客户也可以绕过你的页面,直接POST到你的服务器,所以你在服务端必须处理这个问题。
引发异常,并且你没有进行任何处理,可能导致一个黄页,让你的客户一惊。为了避免显示黄页,初学者大多直接在代码上加一个try-catch进行捕获,并给客户一个友情提示。
try {
string input = TextBox1.Text;
int result = System.Convert.ToInt32( input );
}
catch( Exception ex ) {
//弹出消息框提示客户输入正确数据
}
一旦吃到甜头,初学者发现这段代码可以实现他要的功能,不会过多考虑可维护性,于是会把这个结构向整个表现层复制,最终导致一个混乱的局面。
除了表现层以外,数据访问层也经常需要进行数据类型转换。如果你还在使用原始的Ado.Net,从DataReader获取值。
IDataReader reader = cmd.ExecuteReader();
int result = System.Convert.ToInt32( reader["字段名"] );
同样,为了不引发异常,初学者根据之前的经验,会在调用代码时添加try-catch进行异常捕获。
try {
IDataReader reader = cmd.ExecuteReader();
int result = System.Convert.ToInt32( reader["字段名"] );
}
catch( Exception ex ) {
//有些人会在这里记录错误日志,还有些懒人直接留空,啥也不干
}
所以最终的结果是,只要进行数据类型转换的操作,初学者为了一定的系统健壮性会大量添加异常处理结构,从而导致代码混乱。
另一个选择是,.Net提供了一个不引发异常的类型转换方法,比如,
string input = "";
int result;
if( int.TryParse( input, out result ) == false ){
//处理错误
}
TryParse会返回一个bool值,指示转换是否成功,如果转换失败,你可以记录日志,并显示一个错误。不过大部分人都可能会偷懒,不会在这里进行任何处理。
string input = "";
int result;
int.TryParse( input, out result );
如果你不想引发异常,更不想用try-catch结构来捕获异常,这确实是一个更好的选择,但需要额外定义一个变量,作为out参数来获取值,会造成额外的工作量。
当然,.Net技术也一直处于持续改进中,表现层技术进入到MVC和WPF时代,而数据访问技术也进入到了Entity Framework时代。MVC提供了一个叫做模型绑定的功能,用于将界面上传回的数据映射到控制器操作的参数中,并且这些参数可以支持实体,这是一个非常强大的功能,这样就不需要手工进行赋值了,更不需要类型转换。WPF通过双向数据绑定,Entity Framework通过映射器,都解决了类似问题。
但是,并不是说数据类型转换就毫无用武之地了,考虑一个使用MVC的场景。你在界面上有一个表格,表格的每行都有一个checkbox,你可以打勾以选中某些行,然后你会把每行的实体标识传到控制器。如果实体标识的数据类型使用Guid,你可以用一个IList<Guid>来接收。
public ActionResult 方法名( IList<Guid> ids ) {
}
这一般都行得通。但是,你并不总是可以这样干,出于某些特殊原因,有时候你需要自己在js中用逗号拼接一些Id,或者用一个Hidden把用逗号拼接的Id保存起来,然后作为一个字符串传到控制器。比如” 06d8dcdd-cfad-433c-aec0-87bf613b9457, 684c0c02-93ec-4047-8f16-57e36b50d703”。
public ActionResult 方法名( string ids ) {
}
由于没有自动转换支持,你只好自己动手,这很简单,使用逗号把输入字符串打散成字符串数组,然后遍历每个数组元素,转换成Guid类型,再添加到一个结果集合保存起来就OK了。
public ActionResult 方法名( string ids ) {
List<Guid> result = new List<Guid>();
string[] list = ids.Split( ',' );
foreach( var each in list ) {
result.Add( Guid.Parse( each ) );
}
//在这里把result传到业务层
}
你发现这段代码不仅可以处理带有逗号的字符串,像” 06d8dcdd-cfad-433c-aec0-87bf613b9457, 684c0c02-93ec-4047-8f16-57e36b50d703”,甚至还能处理不带逗号的,比如“06d8dcdd-cfad-433c-aec0-87bf613b9457 “。你非常满意,然后把这一段代码复制到所有需要将拼接字符串转换成集合的地方。
没过多久,你在一个页面发现了Bug,以前测试的时候,都是操作多个Id,这次没进行操作,传过来的字符串是””,你的代码没有进行任何健壮性检测,所以失败了,抛出一个异常“无法识别的 GUID 格式。“。
你安慰自己“这并不算什么技术问题,只是一时疏忽,看我加一个判断,一招将它搞定“。不过在你的下意识里,已经感觉到进行边界测试才是健壮性的关键。
public ActionResult 方法名( string ids ) {
List<Guid> result = new List<Guid>();
if ( !string.IsNullOrWhiteSpace( ids ) ) {
string[] list = ids.Split( ',' );
foreach( var each in list ) {
result.Add( Guid.Parse( each ) );
}
}
//在这里把result传到业务层
}
你现在准备测试一下,传了一个””过来,果然有效,你大赞自己处理BUG的速度惊人,为了给其它地方也添加如此健壮的特性,你打开所有可能用到的页面,找到这几行代码,进行修改,虽然你感觉这确实有点无聊,但还是只有硬起头皮改了。
从上面可以看到,虽然是司空见惯的数据类型转换,也还是有很多值得我们改进的地方。
下一篇我将使用TDD方式把数据类型转换公共操作类开发出来。由于TDD并不是本系列介绍的重点,所以我不会在本文中详细介绍TDD的要点,请大家查看相关资料,如果有空,我会专门写一篇文章来分享我在使用TDD所碰到的障碍以及心得。
.Net应用程序框架交流QQ群: 386092459,欢迎有兴趣的朋友加入讨论。
谢谢大家的持续关注,我的博客地址:http://www.cnblogs.com/xiadao521/
Util应用程序框架公共操作类(一):数据类型转换公共操作类(介绍篇)的更多相关文章
- Util应用程序框架公共操作类(三):数据类型转换公共操作类(扩展篇)
上一篇以TDD方式介绍了数据类型转换公共操作类的开发,并提供了单元测试和实现代码,本文将演示通过扩展方法来增强公共操作类,以便调用时更加简化. 下面以字符串转换为List<Guid>为例进 ...
- Util应用程序框架公共操作类(二):数据类型转换公共操作类(源码篇)
上一篇介绍了数据类型转换的一些情况,可以看出,如果不进行封装,有可能导致比较混乱的代码.本文通过TDD方式把数据类型转换公共操作类开发出来,并提供源码下载. 我们在 应用程序框架实战十一:创建VS解决 ...
- 应用程序框架实战二十一:DDD分层架构之仓储(介绍篇)
前面已经介绍过Entity Framework的工作单元和映射层超类型的封装,从本文开始,将逐步介绍仓储以及对查询的扩展支持. 什么是仓储 仓储表示聚合的集合. 仓储所表现出来的集合外观,仅仅是一种模 ...
- Util应用程序框架公共操作类
随笔分类 - Util应用程序框架公共操作类 Util应用程序框架公共操作类 Util应用程序框架公共操作类(五):异常公共操作类 摘要: 任何系统都需要处理错误,本文介绍的异常公共操作类,用于对业务 ...
- Util应用程序框架公共操作类(十二):Lambda表达式公共操作类(三)
今天在开发一个简单查询时,发现我的Lambda操作类的GetValue方法无法正确获取枚举类型值,以至查询结果错误. 我增加了几个单元测试来捕获错误,代码如下. /// <summary> ...
- Util应用程序框架公共操作类(七):Lambda表达式公共操作类
前一篇扩展了两个常用验证方法,本文将封装两个Lambda表达式操作,用来为下一篇的查询扩展服务. Lambda表达式是一种简洁的匿名函数语法,可以用它将方法作为委托参数传递.在Linq中,大量使用La ...
- Util应用程序框架公共操作类(四):验证公共操作类
为了能够验证领域实体,需要一个验证公共操作类来提供支持.由于我将使用企业库(Enterprise Library)的验证组件来完成这项任务,所以本文也将演示对第三方框架的封装要点. .Net提供了一个 ...
- YTU 2618: B 求类中数据成员的最大值-类模板
2618: B 求类中数据成员的最大值-类模板 时间限制: 1 Sec 内存限制: 128 MB 提交: 430 解决: 300 题目描述 声明一个类模板,类模板中有三个相同类型的数据成员,有一函 ...
- 泛型集合、datatable常用数据类型转换Json帮助类
泛型集合.datatable常用数据类型转换Json帮助类 using System; using System.Data; using System.Configuration; using Sys ...
随机推荐
- Thinkphp3.2.3路径书写注意
尽量不要这样写: ./public/img/a.jpg 应该这样写:__PUBLIC__/img/a.jpg 不然会引起不兼容 如首页地址 http://192.168.1.100/rjshop/时
- C#输出文本树形层次,前或者后自定义空格位数
Indent String with Spaces This example shows how to indent strings using method for padding in C#. T ...
- Linux上Tomcat部署JavaWeb项目
一.安装JDK 配置java的环境变量,修改/etc/profile文件:vi /etc/profile 然后按下字母i进入插入模式, shift+insert粘贴; esc退出编辑; :wq保存退出 ...
- css3新属性object-fit,对页面img处理
1.http://my.xueh5.com/xh5639998239/detail-3661.html 针对其进行深度讲解推荐 http://www.zhangxinxu.com/wordpress/ ...
- 新版startssl 免费SSL证书申请 (实测 笔记 https http2 必要条件)
简单说明: 目前多个大型网站都实现全站HTTPS,而SSL证书是实现HTTPS的必要条件之一. StartSSL是StartCom公司旗下的.提供免费SSL证书服务并且被主流浏览器支持的免费SSL.包 ...
- 【转】你所不知道的Android Studio调试技巧
这篇写Android studio debug技巧个人觉得写得不错,转自:http://www.jianshu.com/p/011eb88f4e0d# Android Studio目前已经成为开发An ...
- android的EditText重新获取焦点问题
在android开发过程中关于EditText在setFocusable(false);后,当需要再次获得焦点输入时设置setFocusable(true);后还是无法获得焦点的问题: 解决办法: 对 ...
- Struct2 csv文件上传读取中文内容乱码
网络上搜索下,发现都不适合 最终改写代码: FileInputStream fis = null; InputStreamReader isr = null; BufferedReader br= n ...
- 纯CSS3制作超级漂亮又实用的加载小图标
先来一张各种效果的预览图,其实代码并不复杂,关键看自己如何运用. <!doctype html> <head> <meta charset="utf-8&quo ...
- System.Web.HttpContext.Current.Session为NULL解决方法
http://www.cnblogs.com/tianguook/archive/2010/09/27/1836988.html 自定义 HTTP 处理程序,从IHttpHandler继承,在写Sys ...