扩展方法浅谈

简介:

看起来代码更便捷了

按MSDN的定义——扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。这里的“添加”之所以使用引号,是因为并没有真正地向指定类型添加方法。

比如,string类型有一个IsNullOrEmpty方法,用于测试某字符串是否为null或空。类似地,有时我们还需要一个方法,来测试某字符串是否为null、空字符串或者包含的字符都是空白字符。传统的一种方法是在像StringHelper这样的类中添加一个IsBlank方法:

复制代码

  
  
public static class StringHelper
{
public static bool IsBlank( string s)
{
if ( string .IsNullOrEmpty(s)) { return true ; }

return (s.Trim().Length == 0 );
}
}
复制代码

在使用时,需要这样:


  
  
string s = null ;
Assert.IsTrue(StringHelper.IsBlank(s));

这样看来,在完成所需功能时,string类型的实例需要另一个类StringHelper的帮助,显得不甚简洁。使用扩展方法,则变成这样:

复制代码
使用扩展方法

   
   
public static class StringExtension
{
public static bool IsBlank( this string s)
{
if ( string .IsNullOrEmpty(s)) { return true ; }

return (s.Trim().Length == 0 );
}
}

// 使用
string s = null ;
Assert.IsTrue(s.IsBlank());
复制代码

所以,扩展方法实际上提供了一种机制,使得代码在访问诸如StringHelper.IsBlank这样的静态方法时更为便捷。它用起来就像是被扩展类型确实具有该实例方法一样

仅仅如此吗?

不过,这种便捷性只是最浅显的好处,我们接着往下看。微软不会仅仅为了这种便捷性就在C#中添加这样一个特性,在LINQ 的演变及其对 C# 设计的影响一文中可以看到,其根源在于向IEnumerator<T>接口添加方法时,如果直接向该接口添加方法,那么不仅仅它的未来实现要实现该方法,现有的实现亦是如此!这就很不现实了。通过扩展方法,只要借助于已有的静态类语法结构就可以实现了,代价要小得多。

上面这个场景体现了在扩展一个类型时扩展方法的价值。还有其它类似的场景:我们希望向一个类添加成员。我们可以直接修改该类,但需要重新编译和部署,有时候可能代价较高;或许可以考虑继承和包装该类,但是存在于上面方法类似的问题;我们甚至不能修改或继承该类,比如string类或第三方组件中的某些类。这时使用扩展方法就可以比较柔和地注入所需的功能了。

这样我们就在代码可扩展性方面有了很强的能力了,于是可以做更多的事情。在此,就不再赘述了,可以参考鹤冲天同学的文章以及斯克迪亚同学的文章

除了上述便捷性与扩展性方面的好处,还有很有价值的额外所得。

对代码可读性的提升

还是看前面IsBlank的例子,在使用时两种方法会有很大的不同:

复制代码

  
  
if (StringHelper.IsBlank(s))
{
// DoSomething...
}

if (s.IsBlank())
{
// DoSomething...
}
复制代码

显然,后者的可读性有了很大的提高。另一方面从职责上来说,IsBlank更像是string的一个属性,将其“添加”到string类型更为合适。

小结

综上所述,扩展方法首先让我们获得了很强的扩展性方面的能力,可以将很多代码抽象为扩展方法,同时它也会让代码变得更为简洁、直接,这样就带来了一个额外的好处:可读性的提升。

参考

扩展方法(C# 编程指南)

LINQ 的演变及其对 C# 设计的影响

c#扩展方法奇思妙用

自用扩展方法分享


本文转自一个程序员的自省博客园博客,原文链接:http://www.cnblogs.com/anderslly/archive/2010/01/18/using-extension-methods.html,如需转载请自行联系原作者。

目录
相关文章
|
安全 API 数据安全/隐私保护
API接口知识小结
应用程序接口API(Application Programming Interface),是提供特定业务输出能力、连接不同系统的一种约定。这里包括外部系统与提供服务的系统(中后台系统)或后台不同系统之间的交互点。包括外部接口、内部接口,内部接口又包括:上层服务与下层服务接口、同级接口。
|
并行计算 算法 测试技术
[Eigen中文文档] 稠密分解方法目录
本文介绍了 Eigen 提供的处理稠密矩阵分解方法的目录。
252 0
|
搜索推荐 流计算 索引
图文检索
图文检索简介
图文检索
|
分布式计算 关系型数据库 MySQL
Spark Streaming实时流处理项目实战笔记——将统计结果写入到MySQL数据库中
Spark Streaming实时流处理项目实战笔记——将统计结果写入到MySQL数据库中
Spark Streaming实时流处理项目实战笔记——将统计结果写入到MySQL数据库中
|
9月前
|
存储 人工智能 搜索推荐
详解MySQL字符集和Collation
MySQL支持了很多Charset与Collation,并且允许用户在连接、Server、库、表、列、字面量多个层次上进行精细化配置,这有时会让用户眼花缭乱。本文对相关概念、语法、系统变量、影响范围都进行了详细介绍,并且列举了有可能让字符串发生字符集转换的情况,以及来自不同字符集的字符串进行比较等操作时遵循的规则。对于最常用的基于Unicode的字符集,本文介绍了Unicode标准与MySQL中各个字符集的关系,尤其详细介绍了当前版本(8.0.34)默认字符集utf8mb4。
2394 82
|
11月前
|
JavaScript 前端开发 API
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第26天】前端技术的飞速发展让开发者在构建用户界面时有了更多选择。本文对比了Vue.js和Angular两大框架,介绍了它们的特点和优劣,并给出了在实际项目中如何选择的建议。Vue.js轻量级、易上手,适合小型项目;Angular结构化、功能强大,适合大型项目。
378 1
ZLMediakit-method ANNOUNCE failed: 401 Unauthorized
ZLMediakit-method ANNOUNCE failed: 401 Unauthorized
381 0
|
算法 API 开发工具
ArcFace
ArcFace 是虹软公司开发的一款人脸识别 SDK,它具有高性能、高精度、高鲁棒性等特点,支持多种人脸检测、识别和跟踪技术,可用于多种场景,如手机解锁、身份认证、人脸支付等。
562 1
|
Oracle 安全 Java
JAVA用Mail发送API的方法步骤教程
使用Java和Mail发送API实现自动化邮件发送,提高效率。步骤包括:1. 安装JDK并配置JAVA_HOME,2. 添加JavaMail库(可通过Maven或官网下载)。配置邮件发送涉及邮件服务器地址、端口和认证信息。创建邮件会话、邮件消息对象,然后使用Transport发送。示例代码展示完整流程。注意处理认证失败、连接问题和邮件发送失败等常见问题。
|
XML JSON API
阿里巴巴关键字搜索接口技术详解
阿里巴巴开放平台提供关键字搜索API,让开发者能高效检索商品信息。接口涉及注册获取API密钥、构建HTTP请求、发送请求并解析JSON或XML响应。功能包括商品查询、排序、筛选、分页及结果格式化。使用流程包括注册、理解文档、构建请求、处理响应和错误管理。注意事项包括遵守规则、关键字优化、高效使用筛选与分页,以及确保数据处理的准确性和跟踪官方更新。此API助力商家和开发者提升搜索效率和业务性能。
321 0