“AI 技术+人才”如何成为企业增长新引擎?戳此了解>>> 了解详情
写点什么

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

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

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

关注

评论

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

「微服务的细节」—— 周期性注册 or 一次性注册

袁世超

微服务

【网络入门】详解常用的基础网络知识(面试常考内容)

dvlinker

网络知识 TCP与UDP 心跳机制与丢包重传 网络命令 抓包分析

在线JSON转YAML工具

入门小站

工具

数据资产管理

奔向架构师

数据资产 数据管理 6月月更

Android 修改系统音量及监听

yechaoa

android 6月月更 AudioManager

linux之我常用的20条命令( 之三)

入门小站

Linux

Java Core 「13」ReentrantReadWriteLock 再探析

Samson

学习笔记 Java core 6月月更

数据库每日一题---第18天:每天的领导和合伙人

知心宝贝

数据库 大数据 前端 后端 6月月更

Any to Any 实时变声的实现与落地丨RTC Dev Meetup

声网

音频 RTC Dev Meetup 生态专栏 语音处理

深挖数据价值,2022隐私计算大赛开启!

Jessica@数牍

隐私计算 大数据技能大赛 隐匿查询性能优化 隐私求交性能优化

Larix真正的去中心化借贷平台,并开启double Mining活动

鳄鱼视界

小红书严打买卖账号及刷量作弊行为:必须维护平台的公信力

石头IT视角

服务治理的工作内容

阿泽🧸

微服务 6月月更

在线文本列表批量添加行号工具

入门小站

工具

军体拳代码

工程师日月

6月月更

百度安全再次亮相高性能计算国际顶会SC 2022 — 采用Fuzzing技术防护高性能计算静默数据损坏安全风险

百度安全

百度安全 百度安全实验室 高性能计算国际顶会 SC 2022 Fuzzing技术防护

leetcode 221. Maximal Square 最大正方形(中等)

okokabcd

LeetCode 动态规划 数据结构与算法

攻防演练中红队的内网横向扩展

穿过生命散发芬芳

6月月更 攻防演练

uni-app进阶之创建组件/原生渲染【day9】

恒山其若陋兮

6月月更

【网络进阶】网络问题排查实例集锦(实战经验分享)

dvlinker

Linux 服务器 网络知识 网络进阶

JVM调优简要思想及简单案例-新生代回收算法

zarmnosaj

6月月更

透过华为军团看科技之变(四):互动媒体(音乐)

脑极体

统一日志

卢卡多多

日志 6月月更

AWS的运营管理类服务

冯亮

云计算 AWS

vue导航路由

小恺

6月月更

一问带你彻底了解JVM-Java虚拟机内存区域详解

派大星

JVM

新课上线 | 每次 5 分钟,轻松玩转阿里云容器服务!

阿里巴巴云原生

阿里云 云原生 容器服务

Hoo虎符研究院 | 币圈后浪D/Bond一个基于ERC-3475标准开发的去中心化债券生态系统平台

区块链前沿News

Hoo 虎符交易所

稳住了,别抖!—— 看GetX 的Worker如何防抖

岛上码农

flutter ios 前端 安卓开发 6月月更

接口测试(apipost、jmeter和python脚本)——测试工具

Xd

Java 后端 接口测试

Discourse 新用户可插入媒体的数量

HoneyMoose

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