参考

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. 智能指针(三):unique_ptr使用简介

    我们知道auto_ptr通过复制构造或者通过=赋值后,原来的auto_ptr对象就报废了.所有权转移到新的对象中去了.而通过shared_ptr可以让多个智能指针对象同时拥有某一块内存的访问权.但假如 ...

  2. 本机不安装Oracle客户端,使用PL/SQL Developer连接远程数据库

    附送PL/SQL Developer11中文版下载地址 1.先到Oracle网站下载Instant Client : http://www.oracle.com/technetwork/databas ...

  3. PowerDesigner之PDM(物理概念模型)

    一.PDM概述 PDM(物理数据模型),通俗地理解,就是在PowerDesigner中以图形化的方式展示和设计数据库. PDM中涉及到的基本概念包括: 表: 列: 视图: 主键: 候选键: 外键: 存 ...

  4. 解决Github访问超慢问题[自己留档]

    解决Github访问超慢问题 Github is so slowly. 这段时间访问 github 都非常慢,google了一下发现是github某个CDN被伟大的墙屏蔽所致. 出问题的应该是这个CD ...

  5. 【python】基础

    [字符串]前后引号必须要匹配,相关函数int(),float(),str(),repr(),format(),还有切片运算符 a = 'text'           单引号指定的字符串必须在一个逻辑 ...

  6. SQL Server 修复数据库 相关 脚本 之 DBCC CHECKDB 用法 来自同事分享

    DBCC CHECKDB 用法详解, 手工修复数据库 1. 快速修复 DBCC CHECKDB ('数据库名',REPAIR_FAST) 2.重建索引并修复 DBCC CHECKDB ('数据库名', ...

  7. Servlet小试

    Java响应Http请求: 1.创建项目 因为对Java环境不是很熟悉,第一步卡住了好长时间, javax怎么引用, 在Java EE 5 Libraries中的javaee.jar中,项目中怎么引用 ...

  8. 使用C#三维图形控件进行曲线曲面分析

    使用AnyCAD.Net三维图图形控件能够计算曲线的切线.法线.曲率.长度等,能够计算曲面的uv切线.法线.面积等. 代码示例一:曲线分析 Platform.LineStyle lineStyle = ...

  9. Html5元素及基本语法

    HTML标签开始标签(opening tag):开放标签结束标签(closing tag):闭合标签 元素定义:HTML元素指的是从开始标签到结束标签的代码(元素以开始标签为起始以借宿标签终止)元素的 ...

  10. MongoDB 创建数据库

    语法 MongoDB 创建数据库的语法格式如下: use DATABASE_NAME 如果数据库不存在,则创建数据库,否则切换到指定数据库. 实例 以下实例我们创建了数据库 runoob: > ...