本系列文章将介绍一些对初学者有帮助的辅助类,这些辅助类本身并没有什么稀奇之处,如何能发现需要封装它们可能更加重要,所谓授之以鱼不如授之以渔,掌握封装公共操作类的技巧才是关键,我会详细说明创建这些类的动机和思考过程,以帮助初学者发现和封装自己需要的东西。创建公共操作类的技巧,大家可以参考我的这篇文章——应用程序框架实战十二:公共操作类开发技巧(初学者必读)

  封装公共操作类,不仅要把技术上困难的封装进来,还需要不断观察自己的代码,以找出哪些部分可以更加简化。本文将介绍一个容易被大家所忽视的东西——数据类型转换。

  数据类型转换可以把某个源类型转换为目标类型,比如把字符串转换为整型。一种选择是,你可以使用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应用程序框架公共操作类(一):数据类型转换公共操作类(介绍篇)的更多相关文章

  1. Util应用程序框架公共操作类(三):数据类型转换公共操作类(扩展篇)

    上一篇以TDD方式介绍了数据类型转换公共操作类的开发,并提供了单元测试和实现代码,本文将演示通过扩展方法来增强公共操作类,以便调用时更加简化. 下面以字符串转换为List<Guid>为例进 ...

  2. Util应用程序框架公共操作类(二):数据类型转换公共操作类(源码篇)

    上一篇介绍了数据类型转换的一些情况,可以看出,如果不进行封装,有可能导致比较混乱的代码.本文通过TDD方式把数据类型转换公共操作类开发出来,并提供源码下载. 我们在 应用程序框架实战十一:创建VS解决 ...

  3. 应用程序框架实战二十一:DDD分层架构之仓储(介绍篇)

    前面已经介绍过Entity Framework的工作单元和映射层超类型的封装,从本文开始,将逐步介绍仓储以及对查询的扩展支持. 什么是仓储 仓储表示聚合的集合. 仓储所表现出来的集合外观,仅仅是一种模 ...

  4. Util应用程序框架公共操作类

    随笔分类 - Util应用程序框架公共操作类 Util应用程序框架公共操作类 Util应用程序框架公共操作类(五):异常公共操作类 摘要: 任何系统都需要处理错误,本文介绍的异常公共操作类,用于对业务 ...

  5. Util应用程序框架公共操作类(十二):Lambda表达式公共操作类(三)

    今天在开发一个简单查询时,发现我的Lambda操作类的GetValue方法无法正确获取枚举类型值,以至查询结果错误. 我增加了几个单元测试来捕获错误,代码如下. /// <summary> ...

  6. Util应用程序框架公共操作类(七):Lambda表达式公共操作类

    前一篇扩展了两个常用验证方法,本文将封装两个Lambda表达式操作,用来为下一篇的查询扩展服务. Lambda表达式是一种简洁的匿名函数语法,可以用它将方法作为委托参数传递.在Linq中,大量使用La ...

  7. Util应用程序框架公共操作类(四):验证公共操作类

    为了能够验证领域实体,需要一个验证公共操作类来提供支持.由于我将使用企业库(Enterprise Library)的验证组件来完成这项任务,所以本文也将演示对第三方框架的封装要点. .Net提供了一个 ...

  8. YTU 2618: B 求类中数据成员的最大值-类模板

    2618: B 求类中数据成员的最大值-类模板 时间限制: 1 Sec  内存限制: 128 MB 提交: 430  解决: 300 题目描述 声明一个类模板,类模板中有三个相同类型的数据成员,有一函 ...

  9. 泛型集合、datatable常用数据类型转换Json帮助类

    泛型集合.datatable常用数据类型转换Json帮助类 using System; using System.Data; using System.Configuration; using Sys ...

随机推荐

  1. mac 终端常用命令

    1.复制文件内容到剪贴板:pbcopy < ~/.ssh/id_rsa.pub. 2.ssh key 的生成,参考mac ssh key 的获取. 3.sourcetree 需要输入的密码,指的 ...

  2. storm 入门原理介绍

    1.hadoop有master与slave,Storm与之对应的节点是什么? 2.Storm控制节点上面运行一个后台程序被称之为什么? 3.Supervisor的作用是什么? 4.Topology与W ...

  3. MVC项目中ExecutionTimeout不生效的解决方案

    我们做web服务器端开发时,经常会遇到一个需求场景,因为某些耗时处理造成页面的响应处理时间超长,技术角度就想能否给页面处理程序一个指定的超时时间,服务端处理程序执行时间超过这个指定的超时时间则中断处理 ...

  4. “LC.exe”错误

    错误“LC.exe”已退出,代码为 -1. 可能的原因是: 这个第三方组件是个商业组件,他在组件的主使用类定义了 LicenseProvider(typeof(LicFileLicenseProvid ...

  5. 【转】Android Studio-1.2版本设置教程

    如果重新安装Android Studio的话要重新配置风格选项啥的,这篇是个很好的教程,原文链接:http://blog.csdn.net/skykingf/article/details/45485 ...

  6. webpack模块加载css文件及图片地址

    webpack支持css文件加载并打包,只需安装相应加载器并在配置文件中配置 . 加载的css文件内容会与该模块里的js内容混合封装,这样做的好处是一个js文件包含了所有的css与js内容,有效减少了 ...

  7. linux开启FTP以及添加用户配置权限,只允许访问自身目录,不能跳转根目录

    1.切换到root用户 2.查看是否安装vsftp,我这个是已经安装的. [root@localhost vsftpd]# rpm -qa |grep vsftpd vsftpd--.el7_2.x8 ...

  8. socket通信

    socket通信 一:socket基于Tcp连接,数据传输有保证 二:socket连接的建立过程: 1:服务器监听 2:客户端发出请求 3:建立连接 4:通信 三:一个简单的例子:服务器端每隔一段时间 ...

  9. 平凡的KTV后台,不平凡的KTV数据

    之前就是说过“一个项目有很多重要的步骤以及功能”,那我们现在就来看看对于KTV项目来说:后台是处于什么样的重要作用! 首先就得了解KTV后台的一些功能了: 1.歌曲管理 .歌手管理 .设置资源路径 2 ...

  10. WPF整理-使用用户选择主题的颜色和字体

    “Sometimes it's useful to use one of the selected colors or fonts the user has chosen in theWindows ...