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; } ...
随机推荐
- CentOS 6 minimal 网络配置
安装CentOS6 minimal 之后ifconfig 只有lo本地 的127.0.0.1 没有局域网ip. 这边我用的是vmware nat DHCP 提供网络服务.过程就不赘述了. 解决笔记 ...
- 最小生成树——kruskal算法
kruskal和prim都是解决最小生成树问题,都是选取最小边,但kruskal是通过对所有边按从小到大的顺序排过一次序之后,配合并查集实现的.我们取出一条边,判断如果它的始点和终点属于同一棵树,那么 ...
- css中的背景、边框、补丁相关属性
css中的背景.边框.补丁相关属性 关于背景涉及到背景颜色与背景图片 背景颜色background-color即可设定: 背景图片background-image即可设定: 但是背景图片还涉及到其他的 ...
- jQuery的选择器中的通配符使用介绍
$("input[id^='data']");//id属性以data开始的所有input标签 $("input[id$='data']");//id属性以dat ...
- Linux Command Line 笔记(1)
Yunduan CUI graphical user interfaces make easy tasks easy, while command line interfaces make diffi ...
- linux常用工具集合
网络: nm-tool 查看网络状态(有线/无线)
- 什么是OAuth授权?
什么是OAuth授权? 一.什么是OAuth协议 OAuth(开放授权)是一个开放标准. 允许第三方网站在用户授权的前提下访问在用户在服务商那里存储的各种信息. 而这种授权无需将用户提供用户名和密 ...
- HackerRank-Longest Subarray
give an array and target value, find the max length of the subarray which sum of the elements is les ...
- jsp静态、动态引入其他jsp
1. <%@ include file="page.jsp"%> /*静态引入,内容必须写成固定值*/ 在servlet容器转化jsp为servlet时,将引入的 ...
- winfrom自定义控件
c#TabControl控件左边选项卡左边显示,文字横向显示 http://blog.csdn.net/kasama1953/article/details/52133713 WinForm中,给Te ...