写点什么

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

  • 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:491989
用户头像

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

关注

评论

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

极客星球 | 开发者服务合规检测护航企业数字生态建设

MobTech袤博科技

信息安全 开发者服务 安全合规检测 SDK检测 数据健康

社区动态|SelectDB 联合传智教育推出免费 Apache Doris 中文视频教程

SelectDB

Doris 开源社区 Apaache Doris 开源治理

Web3生态龙头AQUANEE,即将登录Gate等平台

股市老人

Yarn的RM功能介绍

五分钟学大数据

6月月更

详解大集群通信建模理论公式

华为云开发者联盟

数据库 华为云 查询

天翼云对象存储ZOS高可用的关键技术揭秘

天翼云开发者社区

天翼云践行“双碳”目标 “东数西算”绘画绿色发展新蓝图

天翼云开发者社区

昇腾AI的蝴蝶效应,从智能制造开始

脑极体

淘宝Native研发模式的演进与思考 | DX研发模式

阿里巴巴终端技术

ide 技术选型 native 客户端 动态化

Flink ML API,为实时机器学习设计的算法接口与迭代引擎

Apache Flink

大数据 flink 编程 流计算 实时计算

KusionStack 开源有感|历时两年,打破“隔行如隔山”困境

SOFAStack

开源 编程语言 语言 #Github 运维‘

架构实战营 - 第 6 期 模块八课后作业

乐邦

「架构实战营」

MASA Auth - 从用户的角度看整体设计

MASA技术团队

为什么我们总是说不清「需求是什么」

LigaAI

产品经理 需求 需求分析 产品设计与思考

四川21市州国家反诈中心APP覆盖情况,筑牢全民反诈“防护墙”

易观分析

反诈APP

千万级高并发下看天翼云如何为“健康码”突破技术瓶颈

天翼云开发者社区

Go语言创造者回顾:是什么让GoLang如此受欢迎?

三石

go语言

Flutter 开发一个通用的购物车数量编辑组件

岛上码农

flutter 安卓开发 ios 开发 跨平台应用 6月月更

做多线程并发扩展,这两点你需要关注

华为云开发者联盟

spring 多线程 高并发 开发 华为云

一文读懂天翼云自研TeleDB 数据库五大关键特性

天翼云开发者社区

OKALEIDO的NFT聚合交易,打造面向艺术家的Web3商业生态

股市老人

TICS端到端实践:企业积分查询作业开发

华为云开发者联盟

云计算 华为云 安全计算

SoFlu 软件机器人:辅助企业落地 DevOps 的自动化工具

飞算JavaAI开发助手

手把手教你实战开发黑白棋实时对战游戏

华为云开发者联盟

云计算 软件开发 游戏开发 华为云

见微知著,细节上雕花:SVG生成矢量格式网站图标(Favicon)探究

刘悦的技术博客

前端 favicon SVG svg图 Icon Font

知识图谱看高考,高考加油!高考学子金榜题名

清林情报分析师

数据分析 数据可视化 高考 知识图谱

MySql函数

工程师日月

6月月更

中国企业数字化转型的十大趋势

小炮

Streaming Data Warehouse 存储:需求与架构

Apache Flink

大数据 flink 编程 流计算 实时计算

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