C#中Dynamic的妙用及代码重构
应用场景:检查几个表的特定字段是否为空,字段是否为空是在数据库中进行配置的。前台根据数据中字段的设置,进行动态检查。
原始人版:
private string CheckFieldNull(MONTHINPUTDATA data,IList<ReportTemplate> shownFields)
{
IList<string> result = new List<string>();
if (data.UT_003 != null)
{
var dataObj = data.UT_003;
for (var i = ; i < shownFields.Count; i++)
{
var objName = dataObj.ToString().Substring(dataObj.ToString().LastIndexOf('.') + );
if (shownFields[i].code.CODEVALUE.Replace("_","") == objName)
{
var fs = shownFields[i].FieldList;
Type Ts = dataObj.GetType();
for (var j = ; j < fs.Count; j++)
{
object o = Ts.GetProperty(fs[j].FIELDNO).GetValue(dataObj, null);
if (o == null)
{
result.Add(fs[j].FIELDNAME);
}
}
}
}
}
if (data.UT_012 != null)
{
var dataObj = data.UT_012;
for (var i = ; i < shownFields.Count; i++)
{
var objName = dataObj.ToString().Substring(dataObj.ToString().LastIndexOf('.') + );
if (shownFields[i].code.CODEVALUE.Replace("_", "") == objName)
{
var fs = shownFields[i].FieldList;
Type Ts = dataObj.GetType();
for (var j = ; j < fs.Count; j++)
{
object o = Ts.GetProperty(fs[j].FIELDNO).GetValue(dataObj, null);
if (o == null)
{
result.Add(fs[j].FIELDNAME);
}
}
}
}
}
return string.Join(",",result);
}
这样的代码确实让人纠结。的确,开发者可以几乎不用动脑子,以比较快速度编码(完成一段后,复制、粘贴即可搞定),完成任务。这种编码有一定的灵活性,具体来说就是检查的字段设置(字段由需要检查,变更为不需要检查或者相反)修改后,代码不用变就可以满足要求。不足之处在于有大量的重复代码,而且还应用了硬编码。假如又增加了需要判断的字段表,那么此方法必须修改才行。而且这种写法的代码量很大,也不利于后期维护。总体来说这样的代码质量比较差劲。
OK,既然C# 4.0引入了dynamic,那么我们不妨用此技术简化下代码,于是,就有了第二版的代码,代码如下:
private string CheckFieldNull(MONTHINPUTDATA data,IList<ReportTemplate> shownFields)
{
IList<string> result = new List<string>();
if (data.UT_003 != null)
{
var dataObj = data.UT_003;
string checkResult = CheckSingleFieldNull(dataObj, shownFields);
if (checkResult.Length > )
{
result.Add(checkResult);
}
}
if (data.UT_012 != null)
{
var dataObj = data.UT_012;
string checkResult = CheckSingleFieldNull(dataObj, shownFields);
if (checkResult.Length > )
{
result.Add(checkResult);
}
}
return string.Join(",",result);
} private string CheckSingleFieldNull(dynamic dataObj, IList<ReportTemplate> shownFields)
{
for (var i = ; i < shownFields.Count; i++)
{
var objName = dataObj.ToString().Substring(dataObj.ToString().LastIndexOf('.') + );
if (shownFields[i].code.CODEVALUE.Replace("_", "") == objName)
{
var fs = shownFields[i].FieldList;
Type Ts = dataObj.GetType();
for (var j = ; j < fs.Count; j++)
{
object fv = Ts.GetProperty(fs[j].FIELDNO).GetValue(dataObj, null);
if (fv == null)
{
return fs[j].FIELDNAME;
}
}
}
}
return string.Empty;
}
这样一来,将检查部分抽出来,提炼成一个函数,需要判断的地方进行判断,这样修改下来,代码确实精简了很多,但是....,似乎代码量还是很大,并且还没有解决硬编码(枚举表名)的问题。既然我们是冲着dynamic去的,那么我们不妨再做的彻底些,于是第三版趁着热乎劲出炉了。
private string CheckFieldNull(MONTHINPUTDATA data, IList<ReportTemplate> shownFields)
{
IList<string> result = new List<string>();
Type inputDataType = data.GetType();
for (var i = ; i < shownFields.Count; i++)
{
var fieldNo = shownFields[i].code.CODEVALUE; dynamic fieldValue = inputDataType.GetProperty(fieldNo).GetValue(data, null); if (fieldValue == null)
{
result.Add(shownFields[i].code.CODENAME);
continue;
} string checkResult = CheckSingleTableFieldNull(fieldValue, shownFields[i].FieldList); if (checkResult.Length > )
{
result.Add(checkResult);
}
}
return string.Join(",", result);
} private string CheckSingleTableFieldNull(dynamic field, IList<UVQYJYPERIODREPORT> shownFields)
{
Type inputDataType = field.GetType(); IList<string> result = new List<string>(); for (var i = ; i < shownFields.Count; i++)
{
//字段为目录级别时,不需要判断。
if (shownFields[i].ISDIRECTORY == field_IsDirectory) { continue; } object fieldValue = inputDataType.GetProperty(shownFields[i].FIELDNO).GetValue(field, null); if (fieldValue == null)
{
result.Add(shownFields[i].FIELDNAME);
}
}
return string.Join(",", result);
}
这样一来,完全达到了动态检查字段为空的目的,不再硬编码,完全听命于数据库中有关字段的配置。至此,再无纷扰,天下太平了。
备注:请无视示例代码中函数的参数命名及函数内变量的命名方式(纯粹展示用)。
C#中Dynamic的妙用及代码重构的更多相关文章
- Android Studio在代码重构中的妙用
代码重构几乎是每个程序员在软件开发中必须要不断去做的事情,以此来不断提高代码的质量.Android Stido(以下简称AS)以其强大的功能,成为当下Android开发工程师最受欢迎的开发工具,也是A ...
- C#中dynamic的正确用法
C#中dynamic的正确用法 http://www.cnblogs.com/qiuweiguo/archive/2011/08/03/2125982.html dynamic是FrameWork4 ...
- C#中dynamic的正确用法 以及 typeof(DynamicSample).GetMethod("Add");
dynamic是FrameWork4.0的新特性.dynamic的出现让C#具有了弱语言类型的特性.编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性.比如,即使你 ...
- C#中dynamic、ExpandoObject 的正确用法
原文地址:http://www.cnblogs.com/qiuweiguo/archive/2011/08/03/2125982.html dynamic是FrameWork4.0的新特性.dynam ...
- C#中dynamic的正确用法【转】
dynamic是FrameWork4.0的新特性.dynamic的出现让C#具有了弱语言类型的特性.编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性.比如,即使你 ...
- 【转】C#中dynamic的正确用法
原文:http://www.cnblogs.com/qiuweiguo/archive/2011/08/03/2125982.html dynamic是FrameWork4.0的新特性.dynamic ...
- 解决C#中dynamic类型作为泛型参数的反射问题
C#中dynamic类型作为泛型参数传递过去后,反射出来的对象类型是object,我用老外的这篇博文中的代码跑起来,得出的结果是:Flying using a Object map (a map),将 ...
- C#开发中使用Npoi操作excel实例代码
C#开发中使用Npoi操作excel实例代码 出处:西西整理 作者:西西 日期:2012/11/16 9:35:50 [大 中 小] 评论: 0 | 我要发表看法 Npoi 是什么? 1.整个Exce ...
- 2.C#中通过委托Func消除重复代码
阅读目录 一:重复的代码 二:C#中通过委托Func消除重复代码 一:重复代码 public class Persion { public string Name { get; set; } ...
随机推荐
- NLP中word2vec的CBOW模型和Skip-Gram模型
参考:tensorflow_manual_cn.pdf Page83 例子(数据集): the quick brown fox jumped over the lazy dog. (1)CBO ...
- devexpress xaf 开发中遇到的问题.
devexpress xaf 开发中遇到的问题很多久了就忘记了.每天都把开发内容记录下来,方便大家,方便自己
- 记录一些PHP7RCC1编译问题
1,php7rc1源码编译undefined symboles的问题 自己计划将php7环境部署到cubieboard上,懒得去找别人预编译的版本,所以动手从源码编译,中间遇到了一个小问题,此处记录一 ...
- angularjs 文件上传 如何绑定file表单的change?
ng-change 会失灵 , 唯一的解决方式 是 onchange="angular.element(this).scope().fileNameChanged()"然后利用 n ...
- js-PC版监听键盘大小写事件
//获取键盘按键事件,可以使用keyup. //问题:获取到键盘的按下Caps lock键时,不能知道当前状态是大写.还是小写状态. //解决: 设置一个全局判断大小写状态的 标志:isCapital ...
- ubuntu 配置vim(vimrc)
打开终端:ctrl+alt+t 进入vim文件:cd /etc/vim 打开vimrc文件:sudo gedit vimrc 然后在行末if语句前加上下面的内容," 这个符号为注释,后面内 ...
- 11.12模拟考T1(可持续优化)PS:神奇的东西
1.数列操作 (array.pas/c/cpp) [问题描述] 现在有一个数列,最初包含0个数.现在要对数列操作n次,操作有3类. 1) a k,在数列的最后插入一个整数k 2) s 将最近插入的 ...
- [NOIP2015] 子串(dp)
题目描述 有两个仅包含小写英文字母的字符串 A 和 B.现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一 个新的字符串,请问 ...
- 简易c语言文法
<程序>→<外部声明>|<程序><外部声明> <外部声明>→<函数定义>|<声明> <函数定义>→< ...
- X86 Socket 通信
struct txd_socket_handler_t { int fd; }; txd_socket_handler_t *txd_tcp_socket_create() { txd_socket_ ...