[小技巧]让C#的空值处理变得更优雅
参考
http://www.codeproject.com/Articles/739772/Dynamically-Check-Nested-Values-for-IsNull-Values?msg=4895299#xx4895299xx
http://devtalk.net/csharp/chained-null-checks-and-the-maybe-monad/
介绍
C#中的空值处理,一直是一件比较让人不爽的工作。假设现在有如下类:
public class Union { public string Name { get; set; } } public class Dep {
public Union Union { get; set; }
public string Name { get; set; } } public class Person
{
public Dep Dep { get;set;}
public string Name { get; set; }
}
如果Person.Dep.Union.Name.Length>5,则写入日志,代码该怎么写呢?很可能是这样:
if (person != null && person.Dep != null && person.Dep.Union != null && person.Dep.Union.Name != null && person.Dep.Union.Name.Length > )
{
Console.WriteLine(person.Dep.Union.Name);
}
逻辑语句写得多的各位,对于这样写的繁琐应该深有体会。
对策
1扩展方法在访问对象前,会先进入其对应的静态方法。可以很方便的对this参数进行判断和处理,而不引起nullreference异常;
2委托可以很好的进行扩展方法的后续动作。
我们可以这样写上面的语句
person
.GoTo(p => p.Dep.Union.Name)
.If(n => n.Length >= 5)
.Do(Console.WriteLine);
很简洁,是不是?怎么实现呢?只需加入下列扩展类:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection; namespace LinqTesting
{
public static class Helper
{
class IsNullVisitor : ExpressionVisitor
{
public bool IsNull { get; private set; }
public object CurrentObject { get; set; } protected override Expression VisitMember(MemberExpression node)
{
//it will call this overrided method with higher level node
base.VisitMember(node);
if (CheckNull())
return node; var member = (PropertyInfo)node.Member;
CurrentObject = member.GetValue(CurrentObject, null);
CheckNull();
return node;
} private bool CheckNull()
{
if (CurrentObject == null)
IsNull = true; return IsNull;
}
} public static TReturn GoTo<T, TReturn>(this T root, Expression<Func<T, TReturn>> funcGetValue)
{
var visitor = new IsNullVisitor();
visitor.CurrentObject = root;
visitor.Visit(funcGetValue);
if (visitor.IsNull)
return default(TReturn); return (TReturn)visitor.CurrentObject;
} public static TInput If<TInput>(this TInput o, Func<TInput, bool> evaluator)
where TInput : class
{
if (o == null) return null;
return evaluator(o) ? o : null;
} public static TInput Unless<TInput>(this TInput o, Func<TInput, bool> evaluator)
where TInput : class
{
if (o == null) return null;
return evaluator(o) ? null : o;
} public static TInput Do<TInput>(this TInput o, Action<TInput> action)
where TInput : class
{
if (o == null) return null;
action(o);
return o;
}
}
}
[小技巧]让C#的空值处理变得更优雅的更多相关文章
- 9个小技巧让你的 if else看起来更优雅
if else 是我们写代码时,使用频率最高的关键词之一,然而有时过多的 if else 会让我们感到脑壳疼,例如下面这个伪代码: 是不是很奔溃?虽然他是伪代码,并且看起来也很夸张,但在现实中,当我们 ...
- Lombok让pojo变得更优雅
Lombok 采取注解的形式,标记在pojo上面,在编译后,自动生成相应的方法,像get.set.构造方法等都可以注解一键生成. 引入jar包: <dependency> <grou ...
- C#中泛型方法与泛型接口 C#泛型接口 List<IAll> arssr = new List<IAll>(); interface IPerson<T> c# List<接口>小技巧 泛型接口协变逆变的几个问题
http://blog.csdn.net/aladdinty/article/details/3486532 using System; using System.Collections.Generi ...
- sql server 小技巧(4) Sql server 排序时让空值排在最后
order by coalesce( u.sort, 2147483647) sql server 小技巧 集锦
- ( 译、持续更新 ) JavaScript 上分小技巧(三)
最近家里杂事较多,自学时间实在少的可怜,所以都在空闲时间看看老外写的内容,学习之外顺便翻译分享~等学习的时间充足些再写写自己的一些学习内容和知识点分析(最近有在接触的:复习(C#,SQL).(学习)T ...
- SmartForms 小技巧
1.添加空行,保证每一页有固定的打印的表格行数 上图,每页最多打印13行,数据只有11行,自动添加两个空行补齐 代码如下“ "定义变量: data: l_blank type i. &quo ...
- LoadRunner小技巧集锦
preftest 性能测试工作室,专注于性能测试技术研究(www.AutomationQA.com) LoadRunner小技巧集锦 1.录制脚本中包含中文,出现乱码怎么办? 把录制选项中的Suppo ...
- 今天整理了几个在使用python进行数据分析的常用小技巧、命令。
提高Python数据分析速度的八个小技巧 01 使用Pandas Profiling预览数据 这个神器我们在之前的文章中就详细讲过,使用Pandas Profiling可以在进行数据分析之前对数据进行 ...
- Git小技巧 - 指令别名及使用Beyond Compare作为差异比较工具
前言 本文主要写给使用命令行来操作Git的用户,用于提高Git使用的效率.至于使用命令还是GUI(Tortoise Git或VS的Git插件)就不在此讨论了,大家根据自己的的喜好选择就好.我个人是比较 ...
随机推荐
- CHARINDEX用法
CHARINDEX返回字符串中指定表达式的起始位置. 语法CHARINDEX ( expression1 , expression2 [ , start_location ] ) 参数expre ...
- STL容器迭代器失效分析
连续内存序列容器(vector, string, deque) 对于连续内存序列STL容器,例如vector,string,deque,删除当前iterator会使得后面所有的iterator都失效, ...
- psutil
tar -zxvf psutil-2.1.3.tar.gz cd psutil-2.1.3 python setup.py install 安装是出现报错 error: command 'gcc' f ...
- AX 用代码创建FORM动态加控件,重载动态添加的控件的方法。
eg. 范例:class\RFIDReadWriteForm/Build方法. formRun.controlMethodOverload(true); formRun.controlMethodOv ...
- 检查字符串长度 检查字符串是否为空 用正则表达式验证出版物的ISBN号 用正则表达式验证邮证编码 验证字符串中是否含有汉字
<?php /** * 常用的正则表达式来验证信息.如:网址 邮箱 手机号等 */ class check { /** * 正则表达式验证email格式 * * @param string $s ...
- HBase优化
1.hbase的balance策略是region数量策略,即维持每个regionserver的region数量基本一致,这并未考虑一个table的region可能都落到一个refionserver的不 ...
- leetcode 119
119. Pascal's Triangle II Given an index k, return the kth row of the Pascal's triangle. For example ...
- EasyUI datagrid 复杂表头处理
1:表头固定(前台写) 参照官方:http://www.jeasyui.net/demo/334.html 效果图: 源代码如下: <!DOCTYPE html> <html> ...
- 第六章_PHP数组(二)
这篇随笔是对预定义数组变量的总结.通过预定义数组变量,我们可以获得系统环境.用户对话.表单数据等信息. 1.服务器变量:$_SERVER 利用foreach语句打印$_SERVER中的所有元素: &l ...
- 2_2数据类型与C#部分语法[wp8特色开发与编程技巧]
2_2数据类型 -5min 类型介绍 在上个视频中我们构建了我们第一个应用.这一次我们要来了解下c#的数据类型 众所周知,在我们已认知的世界里,我们把文字分为数字与字符.在程序的世界里面我们把数据分为 ...