写点什么

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

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

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

关注

评论

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

ByteHouse:基于ClickHouse 的实时计算能力升级

字节跳动数据平台

大数据 云原生 flink 消费 kafka Clickhouse 企业号 3 月 PK 榜

好用的Java开发工具:IntelliJ IDEA 2022v2022.3.3汉化激活版

真大的脸盆

Java Mac Mac 软件 Java 开发

还在stream中使用peek?不要被这些陷阱绊住了

程序那些事

Java java8 程序那些事 JDK20

NFTScan 与 DeBox 达成合作,双方在 NFT 社交数据层面展开合作

NFT Research

NFT

CloudCanal 落地 StarRocks 数据迁移同步的实践与思考

StarRocks

数据库

使用流水线插件实现持续集成、持续部署

北京好雨科技有限公司

Kubernetes CI/CD rainbond

软件工程高效学 | 软件的内涵与危机

TiAmo

软件工程 软件开发

Flink 在中泰证券的实践与应用

Apache Flink

大数据 flink 实时计算

面试被怼:技术更新这么快,你还不懂响应式微服务就out了

Java spring 微服务 响应式

百度文库接入文心一言,国内首个生成式AI文档服务即将上线

极客天地

软件测试/测试开发丨一文带你了解接口测试价值与体系

测试人

软件测试 自动化测试 测试开发

JVM 堆体系结构及其内存调优

Java JVM

不可错过!Arm 、Intel 及阿里云等资深技术专家现场解读系统安全

OpenAnolis小助手

系统安全 Meetup 龙蜥社区 sig 机密计算

百度CTO王海峰:全栈AI技术加持,打造新一代大语言模型文心一言

飞桨PaddlePaddle

如何通过Java代码在Word中创建可填充表单

在下毛毛雨

Java 表单 word文档

企业数智化转型不仅是可行的,还是必行!

加入高科技仿生人

人工智能 低代码 制造业 数智化

CCF BDCI“大数据平台安全事件检测与分类识别”赛题,奇点云夺冠

奇点云

数据安全 奇点云 个人信息保护

快速掌握网站监控关键数据:仪表盘的创建与管理

云智慧AIOps社区

监控 监控宝 监控工具 云智慧 网站监控

2023中国儿童防敏市场发展洞察

易观分析

医疗 防敏 儿童

初学后端,如何做好表结构设计?

王中阳Go

Go golang 数据库 表结构 golang 面试

中国全屋智能市场将达万亿级,仅3.5%住宅渗透率拥有巨大潜力

极客天地

adobe安装提示错误“Error:SyntaxError:JSON Parse error:Unexpected EOF”

互联网搬砖工作者

苹果M1芯片的Mac怎么关闭SIP?M1 mac关闭Sip方法教程!

互联网搬砖工作者

软件测试/测试开发丨接口测试必备技能-常见接口协议解析

测试人

软件测试 自动化测试 测试开发

开源订单管理系统

源字节1号

开源 软件开发 小程序开发

软件测试/测试开发丨app自动化测试(iOS)元素定位(新手篇)

测试人

软件测试 自动化测试 测试开发

科技+卫生=智慧公厕,城市焕然一新!

光明源智慧厕所

智慧城市

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