参考

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#的空值处理变得更优雅的更多相关文章

  1. 9个小技巧让你的 if else看起来更优雅

    if else 是我们写代码时,使用频率最高的关键词之一,然而有时过多的 if else 会让我们感到脑壳疼,例如下面这个伪代码: 是不是很奔溃?虽然他是伪代码,并且看起来也很夸张,但在现实中,当我们 ...

  2. Lombok让pojo变得更优雅

    Lombok 采取注解的形式,标记在pojo上面,在编译后,自动生成相应的方法,像get.set.构造方法等都可以注解一键生成. 引入jar包: <dependency> <grou ...

  3. 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 ...

  4. sql server 小技巧(4) Sql server 排序时让空值排在最后

    order by  coalesce( u.sort, 2147483647) sql server 小技巧 集锦

  5. ( 译、持续更新 ) JavaScript 上分小技巧(三)

    最近家里杂事较多,自学时间实在少的可怜,所以都在空闲时间看看老外写的内容,学习之外顺便翻译分享~等学习的时间充足些再写写自己的一些学习内容和知识点分析(最近有在接触的:复习(C#,SQL).(学习)T ...

  6. SmartForms 小技巧

    1.添加空行,保证每一页有固定的打印的表格行数 上图,每页最多打印13行,数据只有11行,自动添加两个空行补齐 代码如下“ "定义变量: data: l_blank type i. &quo ...

  7. LoadRunner小技巧集锦

    preftest 性能测试工作室,专注于性能测试技术研究(www.AutomationQA.com) LoadRunner小技巧集锦 1.录制脚本中包含中文,出现乱码怎么办? 把录制选项中的Suppo ...

  8. 今天整理了几个在使用python进行数据分析的常用小技巧、命令。

    提高Python数据分析速度的八个小技巧 01 使用Pandas Profiling预览数据 这个神器我们在之前的文章中就详细讲过,使用Pandas Profiling可以在进行数据分析之前对数据进行 ...

  9. Git小技巧 - 指令别名及使用Beyond Compare作为差异比较工具

    前言 本文主要写给使用命令行来操作Git的用户,用于提高Git使用的效率.至于使用命令还是GUI(Tortoise Git或VS的Git插件)就不在此讨论了,大家根据自己的的喜好选择就好.我个人是比较 ...

随机推荐

  1. android Camera使用(一)

    现在的App不可避免的要使用到手机的相机功能 首先我们先来介绍下最简单的一个实现方式,启动系统自带的Activity 上代码: public void openCamera() { Intent i= ...

  2. span标签之间的空隙

    出现的问题: 在html中,当有两个以及两个以上的span标签并列的时候,如果任意两个span之间换行书写的话,那么他们在页面上展现的时候往往会有空隙 解决的办法有两个: 1.将两个span标签写在同 ...

  3. hdu1505

    the main algorithm as the 1506 #include <stdio.h> #include <iostream> #include <strin ...

  4. my vimrc

    runtime! debian.vim "设置编码 ,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936 ,ucs-bom,chinese "语言 ...

  5. Java 编译报错:illegal character

    1.检查编译版本:1.5还是1.6 2.重新引用一下Jar包

  6. ASP.NET MVC5 高级编程 第2章 控制器

    参考资料<ASP.NET MVC5 高级编程>第5版 第2章 控制器 控制器:响应用户的HTTP 请求,并将处理的信息返回给浏览器. 2.1 ASP.NET MVC 简介 MVC 模式中的 ...

  7. jQuery中$(function() {});问题详解

    $(function() {});是$(document).ready(function(){ })的简写,最早接触的时候也说$(document).ready(function(){ })这个函数是 ...

  8. 软件工程 speedsnail 冲刺2

    2015-5-6 完成任务:snail的对象: 遇到问题:关闭了speedsnail,背景音乐还在响: 明日任务:snail的移动功能.

  9. 显示或隐藏一个Grid

    The Rowset class contains two methods that can be used to show and hide all rows: ShowAllRows() Hide ...

  10. 配置pxe 自动化安装centos6.7

    dhcp服务器是pxe自动化安装的必要条件,因此先搞定dhcp服务器,yum -y install dhcp,  rpm -ql dhcp查看安装了哪些包,less /etc/dhcp/dhcpd.c ...