写点什么

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

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

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

关注

评论

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

微信小程序开发|宿主环境详解

陈橘又青

9月月更

一张图读懂「融云一站式全生态出海解决方案」

融云 RongCloud

白皮书 社交网络

【IT运维】如何有效保障服务器账号密码安全?

行云管家

运维 IT运维 行云管家 账号安全

leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal 从前序与中序遍历序列构造二叉树(中等)

okokabcd

LeetCode 算法与数据结构

以Vue为代表的提升小程序开发效率框架及工具

Geek_99967b

小程序

我的C/C++技术成长之路

Fire_Shield

程序人生 C/C++ 9月月更

从0到1项目搭建-框架搭建(附源码)

微枫Micromaple

架构 springboot Druid Mybatis-Plus 9月月更

物联网平台简介——产品功能类

阿里云AIoT

大数据 安全 物联网平台 物联网 IoT

【等保小知识】等级保护单项测评包括哪些项目?

行云管家

等保 等级保护 等级测评

多标签用户画像分析跑得快的关键在哪里?

跳楼梯企鹅

技术分享| 快对讲融合视频监控功能设计

anyRTC开发者

监控 音视频 调度 快对讲 GB28181

Docker 的快速入门

Docker 9月月更

日均数亿推送稳定性监控实践

得物技术

Java 设计模式 重构 SLA 企业号九月金秋榜

CISO 需考虑的五项 Kubernetes 安全措施

SEAL安全

Kubernetes 软件供应链安全

SQL就业市场最吃香!解密为什么SQL历经半个世纪仍经久不衰?

雨果

sql

从 OLAP 到指标中台 SaaS,关键指标赋能业务管理

Kyligence

OLAP Kyligence 数据管理 指标中台

kubectl 插件推荐: kubectl-watch

云原生技术社区

k8s 插件 kubectl kubectl插件 kubectl-watch

MySQL DDL执行方式-Online DDL介绍

京东科技开发者

MySQL 数据库 ddl DML Online DDL

VoneBaaS平台让区块链服务触手可得

旺链科技

区块链 产业区块链 VoneBaaS 企业号九月金秋榜

英伟达NVIDIA为何可以在高性能计算GPU中处于不败地位?

GPU算力

MobTech 短信验证 Flutter插件

MobTech袤博科技

flutter ios android

IM跨平台技术学习(二):Electron初体验(快速开始、跨进程通信、打包、踩坑等)

JackJiang

即时通讯IM

异步处理 —— RxJS Observable

掘金安东尼

前端 9月月更

面试突击85:为什么事务@Transactional会失效?

Java快了!

总结了一些vue相关的题目,话说今年前端面试难度好大

bb_xiaxia1998

Vue 前端

前端面试5家公司,被经常问到的vue面试题

bb_xiaxia1998

Vue 前端

Kyligence 入选 Gartner 指标中台创新洞察报告

Kyligence

指标管理 指标中台 数据分析管理

物联网平台功能介绍——产品功能类

阿里云AIoT

大数据 物联网平台 物联网 IoT 设备管理

百度交易中台之资产系统架构浅析

百度Geek说

数据库 架构 资产管理

Wiki在企业内部的应用和管理,如何构建有效的Wiki系统?

Baklib

开发者有话说|从心出发

胖虎不秃头

个人成长

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