1. 静态类到扩展方法:

许多方法可能都适合转为扩展方法,只要具有以下特征:

1)你想为一个类型添加一些成员;

2)你不需要为类型的实例添加更多的数据;

3)你不能改变类型本身,因为是别人的代码

2.声明扩展方法

并不是任何方法都能作为扩展方法使用——他必须具有以下特征:

1)他必须在一个非嵌套的,非泛型的静态类中(所以必须是一个静态方法);

2)他至少要有一个参数;

3)第一个参数必须附加this关键字作为前缀;

4)第一个参数不能有其他任何修饰符(比如out或ref);

5)第一个参数不能是指针类型;

我们将第一个参数的类型称为方法的扩展类型,即指该方法扩展了该类型,代码:

public static class StreamUtil

{

const int BufferSize = 8192;

public static void CopyTo(this Stream input,Stream output)

{

byte[] buffer = new byte[BufferSize];

int read;

while((read = input.Read(buffer,0,buffer.Length)) > 0)

{

output.Write(buffer,0,read);

}

}

}

调用:

Stream responseStream = new Stream();

responseStream.CopyTo();

3. 扩展方法是怎样被发现的

知道怎样调用扩展方法固然重要,但知道怎样不调用同样重要。换言之,你要知道如何实现“非请勿来”。

首先了解编译器怎样决定要使用的扩展方法

如果使用using指令,扩展方法可以像类一样不加限制的在代码中使用。如果编译器认为一个表达式好像是要使用一个实例方法,但没有找到与这个方法调用兼容的实例方法(名称不兼容或参数不兼容)。就会查找一个合适的扩展方法。塔会检查导入的所有命名空间和当前命名空间的所有扩展方法,并匹配那些从表达式类型到扩展类型存在着隐式转换的扩展方法。(编译器怎么找到库中的扩展方法:它会检查类和方法是否具有System.Runtime.CompilerServices.ExtensionAttribute这个特性,它是.NET3.5新增的。但是,编译器不检查特性来自哪个程序集,这意味着即使你的项目面向的是.NET2.0,仍然可以使用扩展方法——只需在正确的命名空间中使用正确的名称来定义自己的属性就可以了(即自己编写一个System.Runtime.CompilerServices.ExtensionAttribute类))

如果存在多个适用的扩展方法,他们可应用于不同的扩展类型(使用隐式转换),那么将使用在重载的方法中应用的 “更好的转换” 规则,来选择最合适的方法。

要注意的一个重点是,如果存在适当的实例方法,则实例方法肯定会先于扩展方法使用。

在c#中,你不能在空引用上调用实例方法,但你可以在空引用上调用扩展方法。

4. 使用思路和原则

如果你觉得代码最重要的就是他的结果,扩展方法肯定相当和你胃口,如果觉得实现更重要,那么显式调用静态方法就显得更清晰,实际上,这是“是什么”和“怎么做“之间的差异

扩展方法(深入理解c#)的更多相关文章

  1. c# 扩展方法初见理解

    个人理解扩展方法是对某些类在不改变源码的基础上添加其他的方法.扩展方法必须是在非泛型的静态类里定义,且第一个参数是要使用this 指定需要扩展的类型. class Program { static v ...

  2. 关于.NET中迭代器的实现以及集合扩展方法的理解

    在C#中所有的数据结构类型都实现IEnumerable或IEnumerable<T>接口(实现迭代器模式),可以实现对集合遍历(集合元素顺序访问).换句话可以这么说,只要实现上面这两个接口 ...

  3. c#扩展方法的理解(二:接口)

    namespace ExtensionInterfaceMethod { class Program { static void Main(string[] args) { //使用接口变量来调用扩展 ...

  4. c#扩展方法的理解(一:初识)

    扩展方法是静态方法,是类的一部分,但是实际上没有放在类的源代码中. 扩展方法所在的类也必须被声明为static C#只支持扩展方法,不支持扩展属性.扩展事件等. 扩展方法的第一个参数是要扩展的类型,放 ...

  5. C#扩展方法的理解

    “扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型.” 这是msdn上说的,也就是你可以对String,Int,DataRow,DataTable等这些 ...

  6. C#扩展方法的理解 (转)

    “扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型.” 这是msdn上说的,也就是你可以对String,Int,DataRow,DataTable等这些 ...

  7. C# 五、谈扩展方法的理解

    http://www.cnblogs.com/zhaopei/p/5678842.html

  8. C#中的反射和扩展方法的运用

    前段时间做了一个练手的小项目,采用的是三层架构,也就是Models,IDAL,DAL,BLL 和 Web , 在DAL层中各个类中有一个方法比较常用,那就是 RowToClass ,顾名思义,也就是将 ...

  9. C#扩展方法学习

    扩展方法的本质是什么,详细见此文 C#扩展方法,爱你在心口难开 重点如下:扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型.扩展方法是一种特殊的静态方法 ...

随机推荐

  1. 分布式监控系统Zabbix-3.0.3-完整安装记录

    由于采用sendmail发送邮件,常常会被认为是垃圾邮件被拒,所以不推荐这种方式!这里,针对zabbix报警信息的发送,可以采用下面两种方式中的任意一种:1)利用sendEmail程序来发送报警邮件. ...

  2. 使用ffmpeg从mp4文件中提取视频流到h264文件中

    ffmpeg -i 2018.mp4 -codec copy -bsf: h264_mp4toannexb -f h264 tmp. 注释: -i 2018.mp4:  是输入的MP4文件 -code ...

  3. 善于利用python中的os模块

    作为一个程序猿,平时善于利用python中的os模块进行路径等操作,会省去很多麻烦,下面总结一下我平时经常用到的方法: import os os.getcwd() # 获取当前文件所在的目录 os.p ...

  4. 【python中单链表的实现】——包括初始化、创建、逆序、遍历等

    # coding=utf-8 class mynode(object): def __init__(self, data, nextnode = None): self.data = data sel ...

  5. UVa 1600 Patrol Robot(三维广搜)

    A robot has to patrol around a rectangular area which is in a form of m x n grid (m rows and ncolumn ...

  6. f5通过vs访问其他站点的源、目的IP问题

    通过VIP访问其他站点,则事实上是从服务器访问到其他站点. 如,域名 a.xin.com解析到vip 10.16.100.47(member为10.16.45.71和10.16.45.72)访问192 ...

  7. 【Linux 线程】同一个进程中的线程共享哪些资源

    进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线 ...

  8. 运行wmic命令异常:java.io.IOException: Cannot run program "wmic": CreateProcess error=2, ϵͳÕҲ»µ½ָ¶解决记录

    之前的一篇博文获取电脑cpu序列号在一同事电脑出现上述异常 百度一下网上只有一位外国网友朋友这个问题(地址),并且还没人回复,你能靠自己了 定位了一下出错代码: Process process = R ...

  9. linq 动态判断

    以前要不是使用扩展方法 要么使用如(t==2&&判断条件)||(s==1&&判断条件) 其实可以简单的实现扩展一个whereIf即可(abp实现),如下所示 ··· / ...

  10. vue-awesome-swiper轮播的使用

    一.安装vue-awesome-swiper npm install vue-awesome-swiper --save 二.引入插件 main.js里面分别引入(记得有些电脑要引入样式) impor ...