写点什么

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

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

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

关注

评论

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

如何把 MySQL 备份验证性能提升 10 倍

Juicedata

MySQL 数据库 云存储 数据备份

直播整理 | TDengine 技术内幕分享:兼容 OpenTSDB

TDengine

数据库 tdengine OpenTSDB

28天写作总结

wood

28天写作

Presto 在字节跳动的内部实践与优化(实践篇)

字节跳动数据平台

大数据 字节跳动 presto

Presto 在字节跳动的内部实践与优化(优化篇)

字节跳动数据平台

大数据 字节跳动 presto

恒源云(GPUSHARE)_[SimCSE]:对比学习,只需要 Dropout?

恒源云

深度学习

面试被问spring ioc,这样说让面试官眼前一亮(1)

公众号:程序猿成神之路

spring 5

模块三作业

cqyanbo

Spring框架基础知识(02)

海拥(haiyong.site)

28天写作 12月日更

大凉山的新衣,产业AI的未来

脑极体

Apache APISIX Dashboard 未授权访问漏洞公告(CVE-2021-45232)

API7.ai 技术团队

漏洞修复 CVE Apache APISIX

模块八

侠客行

「架构实战营」

你只会用 split?试试 StringTokenizer,性能可以快 4 倍!!

CRMEB

在字节,大规模埋点数据治理这么做!

字节跳动数据平台

大数据 字节跳动 埋点 流量 埋点治理

Java 数据持久化系列之JDBC

程序员历小冰

数据库 持久化 28天写作 12月日更

Dubbo的预热与停机实践

快看工程技术中心

dubbo 优雅停机 服务预热

网络安全审计之CMS代码审计

网络安全学海

黑客 网络安全 信息安全 渗透测试 代码审计

2021,用「创新」重新定义ToB

ToB行业头条

[架构实战营] 模块八作业

张祥

架构实战营

数字中国建设再提速,智慧金融发展如何跑出“加速度”?

百度大脑

人工智能 数字化 智能化

1.6(下周四)直播 | 观测云实践学堂03期:K8S太复杂,可观测实践一筹莫展?全新K8S实践干货直播间等你!

观测云

直播

检索、问答、情感分析场景前沿技术方案分享!

百度开发者中心

自然语言处理

怎么借助Camtasia制作回忆录

淋雨

Camtasia 录屏 luping

2021年末28天写作营总结

mtfelix

28天写作

物业资产管理系统解决方案

低代码小观

低代码 企业管理 资产管理 CRM CRM系统

百度智能云开物秀出全年成绩,发布和升级五大新产品

百度大脑

人工智能 百度

httprouter源码刨析

王博

一套架构框架如何满足流批数据质量监控

字节跳动数据平台

大数据 字节跳动 数据质量

NFG定期赚币专场在虎符开启 APY高达1200%

区块链前沿News

Hoo虎符 虎符交易所

网络编程懒人入门(十三):一泡尿的时间,快速搞懂TCP和UDP的区别

JackJiang

TCP 网络编程 udp 即时通讯 IM

59 K8S之Elasticsearch节点

穿过生命散发芬芳

k8s 28天写作 12月日更

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