写点什么

使用扩展方法对调用进行验证

  • 2009-03-27
  • 本文字数:1347 字

    阅读完需:约 4 分钟

利用 C# 3.0 提供的扩展方法技术,可以为已经编译好的程序集类型增加新的方法,从而应对新的扩展。除了在可扩展性方面所具有的优势之外,如果能够合理地结合泛型与类型推断,扩展方法还可以有效降低代码的重复,提高程序的可重用性。例如,这样的方法实现:
public class CustomerDAL
{
public IEnumerable FindCustomers(string roleName)
{
return from customer
in context.Customer
where customer.RoleName.Equals(roleName)
select customer;
}
} 调用如下方法,可能抛出 NullReferenceException 异常:

Customer customer = new CustomerDAL().FindCustomers(Role.Admin).First(); 我们需要对返回结果进行验证,如果返回为 null,则可以抛出自定义异常,或者创建一个空对象,例如:

public IEnumerable FindCustomers(string roleName)
{
IEnumerable customers = from customer
in context.Customer
where customer.RoleName.Equals(roleName)
select customer;
if (customers == null)
{
throw new MyException(“Cann’t find the customers.”);
}
return customers;
} 如果系统有许多方法都需要对返回结果进行验证,则这样的验证逻辑就会充斥在各个方法体中,既不利于重用,也会对未来的修改造成极大的阻碍。当然,我们可以引入 Null Object 模式来替代对 null 值的判断逻辑,但这种方式仍然需要为多种类型定义不同的 Null Object 类型。

Craig Andera 在其博客文章中提出使用扩展方法对调用进行验证。他写道:

NullReferenceException 异常会抛出,但是我们希望有更具体的异常信息。因此,我们编写了如下的扩展方法:

public static T OrThrow(this T obj, Exception e) {
if (obj == null) {
throw e;
}
return obj;
}

利用 OrThrow 扩展方法,则之前的调用方式可以修改为:

Customer customer = new CustomerDAL().FindCustomers(Role.Admin).OrThrow(new MyException(“Can’t find Customer”)).First();

Craig Andera 提出:

OrThrow 扩展方法对于你所要调用的类型而言是通用的,并且它返回了该类型,所以你可以将其插入到表达式链中,而不会丢失智能感应功能。并且因为类型推断功能,实际上并不需要指定具体的类型。

也就是说,OrThrow 扩展方法可以应用到任何类型上,因此它可以在各种类型上重用非空验证甚至是调用验证。借鉴这一思想,我们还可以利用此方法默认实现对象实例的创建,以避免抛出 NullReferenceException 异常,例如:
public static T Instance(this T obj) where T:new()
{
if (obj == null)
{
obj = new T();
}

return obj;
}

由于 Instance 扩展方法中的类型参数 T 需要创建实例,因此必须添加 new() 约束。所以该扩展方法存在一定的局限,例如无法应用在之前的 IEnumerable 类型上。但对于如下的方法却非常有效:
public class ListObject
{
public List Foo()
{
return null;
}
}

通过 Instance 扩展方法,可以安全地调用 List 的相关属性和方法,例如 Count 属性:
Console.WriteLine(new ListObject().Foo().Instance().Count);

控制台打印出来的结果为 0。如果没有 Instance 扩展方法,则会抛出 NullReferenceException 异常。

作为 C# 3.0 增加的新特性,扩展方法在大量项目中得到了广泛地应用,但绝不仅仅是提高可扩展性这么简单。在进行项目开发时,若能适当地考虑使用扩展方法,说不定会带来出奇制胜的效果。

2009-03-27 21:491658
用户头像

发布了 109 篇内容, 共 41.2 次阅读, 收获喜欢 14 次。

关注

评论

发布
暂无评论
发现更多内容

一键生成rpc网关服务项目代码,让你轻松实现跨语言、跨平台的服务调用

vison

微服务 Go 语言 gin 代码自动生成 rpc gateway

从软件哲学角度谈 Amazon SageMaker

亚马逊云科技 (Amazon Web Services)

Amazon SageMaker

什么是软件开发领域的 disruptive innovation

汪子熙

软件工程 软件开发 三周年连更

多维评测指标解读2022MSU世界编码器大赛结果

阿里云CloudImagine

云计算 编码 编码器 视频云 MSU

《爱在黎明破晓前 | 我有话要说》

后台技术汇

三周年连更

华为阅读联手20余家头部内容平台,共建数字化阅读

最新动态

Spring Boot之根据数据库连接信息指定分页查询表结构信息

bug菌

Spring Boot 2 spring-boot 三周年连更

Qz学算法-数据结构篇(非线性结构、树)

浅辄

数据结构 三周年连更

程序员失业:现实还是幻想?| 社区征文

断墨寻径

人工智能 三周年征文

【直播回顾】3月银行APP用户体验评测+中国金融业财富管理AI应用分析

易观分析

金融 银行

挑战 30 天学完 Python:Day13 列表推导式和Lambda

MegaQi

挑战30天学完Python 三周年连更

如何在 Linux 中查看正在运行的进程?这三个命令轻松实现!

wljslmz

Linux 三周年连更

干货|SpringBoot JMS(ActiveMQ)API实践应用详解

浅羽技术

Apache 中间件 ​ActiveMQ 消息列队 三周年连更

Bitmap引起的OOM问题

芯动大师

App 三周年连更 Out Of Memory

基于STM32+华为云设计的智慧烟感系统

DS小龙哥

三周年连更

在oracle apex中的Dialog的做法(第一部门):

back_wang

oracle dialog oracle ebs ebs

Selenium操作已经打开的浏览器

IT蜗壳-Tango

三周年连更

Go的内存模型:如何保证并发读写的顺序性?

Jack

ChatGPT-4!又双叒叕写了一本量化交易的书(附下载)

量化投资与机器学习

机器学习 量化投资 ChatGPT4 对冲基金 Quant

Java 中的 null 到底是什么?

Java架构历程

Java 三周年连更

【Python实战】Python采集图书信息

BROKEN

三周年连更

2023 年要避免的 17 个致命的网站设计错误

海拥(haiyong.site)

三周年连更

Git 速查表:初学者必备的 12 个 Git 命令

Se7en

大数据集群的部署实例

TiAmo

大数据 集群 三周年连更 开发实例

【Linux】之Jumpserver堡垒机的部署_搭建

A-刘晨阳

Linux 跳板机 三周年连更

深入理解vue2.x双向数据绑定原理

不叫猫先生

Vue vue响应式 三周年连更

2023移动端技术探索

轻口味

android 移动端 行业趋势 三周年连更

《详谈·张勇》

石云升

读书笔记 三周年连更

iOS MachineLearning 系列(9)—— 人物蒙版图生成

珲少

sdn网络

乌龟哥哥

三周年连更

《一文带你读懂:云原生时代业务监控》

后台技术汇

三周年连更

使用扩展方法对调用进行验证_.NET_张逸_InfoQ精选文章