扩展方法(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. Eclipse自动补全调教

    方法来自http://www.cnblogs.com/sunjie21/archive/2012/06/28/2567463.html 调教后可以做到: 1. sout + Tab 输出System. ...

  2. js 事件模型详解

    把js的事件模型,分为两类,DOM0级和DOM2级, DOM0级 通常直接在DOM对象上绑定函数对象,指定事件类型,dom.onClick = function(){};类似于这种写法,移除事件,则直 ...

  3. [AtCoder3856]Ice Rink Game - 模拟

    Problem Statement An adult game master and N children are playing a game on an ice rink. The game co ...

  4. spring-cloud-Zuul学习(二)【基础篇】--典型配置【重新定义spring cloud实践】

    -- 2019-04-15 20:22:34 引言 上一节是一个最基本的zuul网关实例,它是整个spring-cloud生态里面“路由-服务”的一个缩影,后续也就是锦上添花.这节主要讲述zuul的一 ...

  5. 判断以xx开头的字符串

    public static void main(String[] args) { String str = "EAN_13,1534651"; String strHttp = & ...

  6. 利用RTL2832u电视棒芯片追踪民航飞机轨迹

    我国民航飞机通讯的频率为1090Mhz,而rtl2832u电视棒芯片可以接受的频率范围为24 – 1766 MHz(通过改制Q通道可以接收0-30Mhz的短波)下面开始介绍利用rtl2832u电视棒芯 ...

  7. 吴恩达机器学习笔记52-异常检测的问题动机与高斯分布(Problem Motivation of Anomaly Detection& Gaussian Distribution)

    一.问题动机 异常检测(Anomaly detection)问题是机器学习算法的一个常见应用.这种算法的一个有趣之处在于:它虽然主要用于非监督学习问题,但从某些角度看,它又类似于一些监督学习问题. 给 ...

  8. ansible基础-加密

    一 简介 注:本文demo使用ansible2.7稳定版 众所周知,ansible是很火的一个自动化部署工具,在ansible控制节点内,存放着当前环境服务的所有服务的配置信息,其中自然也包括一些敏感 ...

  9. [Swift]LeetCode930. 和相同的二元子数组 | Binary Subarrays With Sum

    In an array A of 0s and 1s, how many non-empty subarrays have sum S? Example 1: Input: A = [1,0,1,0, ...

  10. linux终端文本编辑神器vi的使用

    vi —— 终端中的编辑器 目标 vi 简介 打开和新建文件 三种工作模式 常用命令 分屏命令 常用命令速查图 01. vi 简介 1.1 学习 vi 的目的 在工作中,要对 服务器 上的文件进行 简 ...