写点什么

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

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

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

关注

评论

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

户外全彩LED屏幕可以做成什么样的造型?

Dylan

广告 LED LED display LED显示屏 LED屏幕

抓住AI时代机遇,从伙伴与华为共筑行业解决方案开始

脑极体

AI

初识华为RazorAttention

zjun

国产替代势不可挡:大型企业ERP国产替代的挑战与机遇

用友BIP

ERP 国产替代 用友BIP 数智底座

践行低碳行动!北京地铁签约用友

用友BIP

数智化 用友BIP 智能财务 北京地铁

科技向善|智源联合南开大学HLT Lab开源两大中文语音数据集,填补老幼人群语音研究空白

智源研究院

XEOS 与 AutoMQ 推出联合方案,共筑云原生 Kafka 新生态

AutoMQ

云计算 大数据 云原生 XSKY AutoMQ

征文大赛 |「码」上数据库—— KWDB 2025 创作者计划启动

KaiwuDB

征文大赛 征文活动 征文投稿 数据库、 KaiwuDB 分布式多模数据库

共探 AI 硬件未来图景,火山引擎“智变浪潮”技术沙龙圆满落幕

火山引擎边缘云

AIOT AI 大底座 AI 数据基础设施

三级等保测评的企业需要做什么准备?

黑龙江陆陆信息测评部

高质发展,匠心智造!狄耐克荣获“2025年度中国精工品牌”荣誉称号

新消费日报

Cursor 在前端需求开发工作流中的应用|得物技术

得物技术

前端 AI‘’ cursor

如何在线绘制roadmap路线图?5个简单易用的路线图软件盘点!

职场工具箱

在线白板 办公软件 AIGC 路线图 技术路线图

条件锁存在的意义:用生活中的例子秒懂线程间的"暗号系统"

不在线第一只蜗牛

Java

Kube Scheduler 可观测性最佳实践

观测云

Kubernetes

爬虫 API 科普:一文搞懂网络数据抓取的门道

代码忍者

API 接口

飞机电气系统技术分析:数字样机技术引领创新

DevOps和数字孪生

腾讯云服务器怎么对接高防

网络安全服务

CDN DDoS 腾讯云服务器 高防IP DDoS 攻击

什么是BTC铭文?什么是MSKE马斯克铭文?

MSKE铭文

区块链 数字货币 MSKE铭文 马斯克铭文 比特币铭文

《Operating System Concepts》阅读笔记:p586-p586

codists

操作系统

去中心化云算力(PowerVerse)是如何提供算力服务的?

PowerVerse

智能合约 去中心化 算力 #区块链 AI‘’

企业多分支机构组网有哪些难点?怎么解决?

Ogcloud

SD-WAN 企业组网 SD-WAN组网 异地组网 分支组网

吉利汽车采用 EMQX 与AutoMQ联合方案构建公私有云一体化的车联网核心架构

AutoMQ

云计算 大数据 混合云架构 AutoMQ 吉利汽车

过剩与稀缺:现代社会的思考与启示

TechLead Studio

个人成长

升级数智底座:企业AI规模化应用的“中国解法”

用友BIP

科技 用友BIP 数智底座 国产大模型 企业AI

DApp开发必看!全球合规白皮书:DAO治理+跨链技术落地策略

区块链软件开发推广运营

交易所开发 dapp开发 链游开发 公链开发 代币开发

zk源码—数据节点与Watcher机制及权限

不在线第一只蜗牛

源码 架构 zk

什么是鱼骨图,怎么用AI制作鱼骨图?4个鱼骨图生成工具盘点!

职场工具箱

人工智能 效率工具 AI软件 AIGC 鱼骨图

博睿数据全面接入DeepSeek:运用AI 铺就大模型可观测性进阶之路

博睿数据

博睿数据 DeepSeek v3

新版 Midjourney V7 支持语音生图;语音 AI 平台 Phonic 融资 400 万美元,构建自主端到端模型丨日报

RTE开发者社区

KubeEdge边缘设备管理系列(五):Mapper-Framework设备数据写入

华为云原生团队

云计算 容器 云原生

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