参考

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. CSS垂直水平居中方法整理

    CSS定位中常常用到垂直居中,比如覆盖层上的弹框. 兼容性比较好的方法: <!DOCTYPE html PUBliC "-//W3C//DTD XHTML 1.0 Transition ...

  2. AceAdmin In MVC之控件

    AceAdmin有很多Html控件,而下载下来之后全部混杂在一起,想用一个控件有时得调整半天,干脆整理出一个版本,而且结合起来MVC的封装.以后就不用一个js css的调了. 在MVC中Html的控件 ...

  3. WPF和WINFORM的互操作

    在WPF中使用Winform控件 <Window x:Class="WPFApplication.Window1" xmlns="http://schemas.mi ...

  4. Find out who the “mole” is?

    Blueheat Company’s  production server was out of order again. The CEO was very upset and want their ...

  5. poj1008_Maya_Calendar

    历法的转换. #include <stdio.h> #include <math.h> #include <string.h> ][]={ "pop&qu ...

  6. 隐藏DLL

    先来推广一下QQ群:61618925.欢迎各位爱好编程的加入. 在外挂或者病毒中,经常需要隐藏掉自己注入的DLL,以免被发现.下面就是一个隐藏DLL的通用模块,用的时候只需要加入到相关模块中即可. 详 ...

  7. c# winfrom应用程序关闭任务管理器中的进程

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  8. Creating a Unique File Name

    If you are working with files or file attachments in PeopleCode, you will typically want to create a ...

  9. [leetcode]_Balanced Binary Tree

    第四道树题,逐渐能写递归了.虽然最后AC的代码还是看了网络,但是距离成功攻克此类问题仅一步之遥. 题目:一棵树,判断是否为AVL.(AVL条件:树上任意一点的左右子树的高度差<=1) 思路:树依 ...

  10. JavaScript的闭包是什么意思以及作用和应用场景

    JavaScript闭包 1.什么是闭包 百度百科对于闭包的解释是:闭包是指可以包含自由(未绑定到特定对象)变量的代码块:这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中 ...