扩展方法(Extension Methods)是C#3.0时引入的新特性,相信很多人都听过并且也都用过,最常见的是在LINQ中的使用。

不仅如此,在开发中,我们也可以创建自己扩展方法,使用它来优化类的设计、简化代码。本文将简单地介绍扩展方法的概念、定义、使用场景以及要注意的点。

一、概念

扩展方法是一种特殊类型的静态方法。对于一个C#类型,如类(包括密封类)、值类型、接口等,扩展方法可以在不改变该类型源码的前提下,为它的实例提供新的成员。因此,若要为一个框架或第三方库的某个类型增加辅助功能,通过扩展方法就可以轻而易举地实现,这也是“扩展”的意义所在。

二、如何定义

创建扩展方法很简单,有以下几个步骤:
1、创建一个静态类;
2、在其中创建一个静态方法;
3、为这个静态方法添加至少一个参数,并在第一个参数前加上this关键字,这个关键字会告诉编译器当前方法是一个扩展方法。而这个方法将成为第一个参数所属类型的新成员。
以下一个典型的扩展方法,用于为枚举值提供一个可获取其DescriptionAttribute特性值的方法:

注意:只有在引用扩展方法所在的静态类的命名空间后,才能使用它;否则,直接调用会编译失败。上例中,使用该扩展方法要引用TLA.Infrastructure.Extensions命名空间。

三、何时使用

从扩展方法的概念上,不难看出,它可以用在以下几种场合:
1、要为某个类型扩展功能,但没有其源码,比如某个框架或第三方库中的一个类;例如,想要获取一个列表中所有的奇数项,就可以为IList<T>接口增加一个扩展方法,这里的IList<T>接口本身是.NET框架中的接口。

2、即使可以访问原有类型的源码,也可以使用扩展方法为它添加辅助功能;

3、重用代码,使代码更简洁;由于扩展方法封装了一段完整的逻辑,所以,使用扩展方法就避免了复制粘贴代码的情况。上例中扩展方法的内容也符合这种使用场景。

四、注意事项

以下是定义与使扩展方法时的一些注意事项和最佳实践:
1、扩展方法本质上是为原有类型提供辅助功能,因此,在创建时,要确保它具有实际意义,且遵循单一职责原则;也即,不能过度使用扩展方法并且它能够完成一个具体、完整的功能;
2、扩展方法本身具有通用性,因此,它里面应避免特定的业务数据类型及其相关逻辑;
3、如果为接口增加扩展方法,扩展方法的命名空间可以与接口的一致;否则,应尽量避免与原类型写在同一命名空间下,这样会“污染”原类型。建议的做法是为扩展方法所在的类设定一个单独的命名空间,如:<Company>.<Product>.Extentions。不过,这样做也有缺点:在操作原有类型的实例时,如果不引用扩展方法所在的命名空间,那么,它就不容易被发现,而解决这个问题的办法是,尽量将扩展方法文档化,并告诉项目组的其他开发人员;
4、为接口增加扩展方法后,则所有实现此接口的类都会包含该扩展方法;
5、在扩展方法中,要对第一个参数进行非空检查,如果为空,应抛出ArgumentNullException(参数为空)异常。

.NET: 谈谈C#中的扩展方法的更多相关文章

  1. C#3.0中的扩展方法

    在实际应用中,开发者完成代码的编译后,除非重新编译更改后的代码,否则开发者很难在原有代码中添加新的功能. 在C#3.0中,提供了一个扩展方法的新特性,可以使得开发者在编译后的程序集里边添加相关的方法, ...

  2. 记录C#中的扩展方法

    C#中的扩展方法. 系统自带的类型,我们无法去修改: 修改源代码需要较大的精力,而且可能会带来错误: 我们只是需要一个或者较少的几个方法,修改源代码费时费力: 被扩展的类是sealed的,不能被继承: ...

  3. C#编程(六十一)------------LINQ中的扩展方法

    原文链接: http://blog.csdn.net/shanyongxu/article/details/47208401 LINQ中的扩展方法 LINQ中where扩展方法,要想使用,必须导入us ...

  4. objective-C中的扩展方法与partial class

     在c#中要扩展一个现有类非常easy,比方这样: ? 1 2 3 4 5 6 7 public static class Utils {     public static void PrintTo ...

  5. C#中的扩展方法(向已有类添加方法,但无需创建新的派生类型)

    C#中的扩展方法 扩展方法使你能够向现有类型"添加"方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样 ...

  6. C#中的扩展方法

    扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用. 以上是msdn官网对扩展方 ...

  7. Enum扩展及MVC中DropDownListFor扩展方法的使用

    public enum SearchState { /// <summary> /// 全部 /// </summary> [Description("全部" ...

  8. 19.C#逐一介绍IEnumerable和IEnumerable<T>中的扩展方法(10.3-10.5)

    今天没有太多的言语,只有代码,扩展方法多得太多,不能一一列完,书中一些,看多了也就会使用了. //Enumerable.Range 返回起始到结束范围,是一个Enumrable<int>类 ...

  9. MVC 中使用扩展方法

     扩展方法(Extension Method)是给那些不是你拥有.因而不能直接修改的类添加方法的一种方便的办法. 一.使用扩展方法 1.定义一个购物车的类-ShoppingCart using Sys ...

随机推荐

  1. [LeetCode] Fibonacci Number 斐波那契数字

    The Fibonacci numbers, commonly denoted F(n) form a sequence, called the Fibonacci sequence, such th ...

  2. PyCharm下载及使用

    PyCharm教育版是一款能够对你编写Python程序的工作有所帮助的免费编译器. PyCharm-community下载链接:https://pan.baidu.com/s/1Hwd_TOVA3en ...

  3. f12 headers 变字典快捷方式

  4. vue项目实践-前后端分离关于权限的思路

    前后端分离后权限的思路 最近看到许多关于权限的思路,但好像都是使用动态加载路由的方式,现在也分享下我在项目中使用的解决方案. 前后端分离关于权限的处理每个人都不一样,根据项目选择制定合适的方案就好 我 ...

  5. 选择 25k 的 996 还是 18k 的 965

    阅读本文大概需要 3.7 分钟. 文中部分内容来源:http://h5ip.cn/hSDk 最近的 996.ICU 话题持续在火爆,一般热点新闻的热度持续时间为一星期,这次是程序们的集体发声导致,戳中 ...

  6. JavaScript基础系列

    JavaScript基础系列 JavaScript是一种基于对象和事件驱动的客户端脚本语言. JavaScript的注释 // 单行 /**/ 多行注释 JavaScript变量,函数名和操作符都是区 ...

  7. [Swift]LeetCode17. 电话号码的字母组合 | Letter Combinations of a Phone Number

    Given a string containing digits from 2-9 inclusive, return all possible letter combinations that th ...

  8. [Swift]LeetCode47. 全排列 II | Permutations II

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  9. [Swift]LeetCode293. 翻转游戏 $ Flip Game

    You are playing the following Flip Game with your friend: Given a string that contains only these tw ...

  10. 非对称加密技术中,iFace [ 爱妃链 ]人脸密钥技术排名第三,将弥补区块链现有不足

    最近,区块链领域,出现了一个比较热门技术的讨论,人脸密钥技术,可能大家还对这个名词感到很陌生,但是熟悉加密技术的技术大牛可能一听就能够明白大体的意思了,但是也正是这一熟悉而陌生的技术名词,掀起了区块链 ...