惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - Anders Cui

jieba.NET与Lucene.Net的集成 jieba中文分词的.NET版本:jieba.NET 迷人的斐波那契数 - Anders Cui 趣题一则:交替放置的碟子 趣题一则:冯·诺依曼邻居问题 - Anders Cui 趣题一则:寻找那扇门 HashSet的实现(下) HashSet的实现(上) 趣题一则:如何快速过桥? 制作自己的wikibook 玩儿一下Word Search Puzzle 整数的展开 离散数学拾趣(三):集合的子集有多少个 - Anders Cui 找零钱的两种方法 离散数学拾趣(二):逻辑难题 离散数学拾趣(一) 关于命名中的数量和人称 意外之喜 最近遭遇的两个VS配置
扩展方法浅谈
Anders Cui · 2010-01-18 · via 博客园 - Anders Cui

扩展方法浅谈

2010-01-18 22:01  Anders Cui  阅读(6181)  评论()    收藏  举报

看起来代码更便捷了

按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#扩展方法奇思妙用

自用扩展方法分享