今天的话题,我们来聊下扩展方法,自己也真心感叹自己的文笔,那叫一个惨啊,回顾写的文章,看着看着也忘记当时是怀着什么心态写的,哈哈,现代人真心是太随性了,可能也是太冷漠了,接着写的吧,总是会有帮助,也会有收获的。

  扩展方法是从C#3开始出现在我们的眼前,它即有静态方法的优点,也使我们的代码更具可读性,可以像实例方法一样调用静态方法。在扩展方法没有出现前,我们在代码中常常出现静态的工具类(当然,即使现在我们来会使用静态工具类,那都是前人的智慧结晶),如一个字符串帮助类、时间转换工具类。想像一下,当我们得到一个封装好的类库,里面的源代码是不可见,我们只是类库的使用者,但类库的开发者也不是十全十美的思路,总是会有一些遗漏。我们拿简单的来说,比如现在我拿到一份代码,代码中有一个Room类,如下:

 class Room
{
public string Name { get; set; }
}

  上面的代码是不能修改的,想象一个我们可以使用什么方法给对象的Name属性赋值?我们可以使用实例一个Room对象,直接赋值,但现在我想给Room类加一个SetName的方法,那扩展方法会帮助到我们。如:

 static class RoomExt
{
public static void SetName(this Room room, string name)
{
room.Name = name;
}
} Room room = new Room();
room.Name = "草堂";
Console.WriteLine(room.Name);
room.SetName("澡堂");
Console.WriteLine(room.Name);
Console.ReadKey();

  上述代码中,SetName方法就是Room类的扩展方法,可以像调用实例方法一样调用它。Room类的开发者忘记给Room类增加一个SetName方法,那我们就使用扩展方法给Room类加一个方法,调用的方式和实例方法一样。SetName的第一个参数为扩展类型,指定要扩展的类,并使用关键字this,规定而已,请遵守之。方法的修饰符为static,呵呵,遵守之。如果我们写的代码是外部调用的话,请使用public关键字,使用pirvate关键字,那就只能在为其扩展的扩展方法中才能使用。

 room.SetName("澡堂"); //调用SetName方法,内部会实现为RoomExt.setName(room,"澡堂")

  上面的代码是不是和我们的静态工具一样,是的,使用扩展方法,可以使用代码更具可读性。当然上述的代码只是一个简单使用,在我们正常使用中,自己写的类肯定会加入合适的实例方法,即使是类库的,那也会让类库开发者加一个方法。但如果是微软的开发者没给出合适的方法,没办法,自己加吧。所以扩展方法经常被我们用来扩展系统类型的方法。扩展方法类似静态方法,但它也必须要具有以下的特征:

  1. 它必须在一个非嵌套的、非泛型的静态类中,如RoomExt类
  2. 它至少要有一个参数
  3. 第一个参数不能使用其它修饰符(ref和out)
  4. 第一个参数必须使用this关键字修饰
  5. 第一个参数的类型不能是指针类型

  找到合适的方法

  当我们使用SetName时,会先在实例方法中找,是否有这个方法,如果没有,会从引入的命名空间中找签名符合的方法,也有可能全有重载情况发生,那基于"谁更优"找到方法并执行。

  对空类型进行扩展

  实际上是对object对象进行扩展,如

 static class objectExt
{
public static bool IsNull(this object o)
{
return o == null;
}
}

  使用如下:

 static class objectExt
{
public static bool IsNull(this object o)
{
return o == null;
}
} Room room1 = null;
Console.WriteLine(room1.IsNull());

  使用是不是很生动,如果你愿意也可以在类中加一个实例方法IsNull,或者使用静态工具来判断一个实例是否为null。实例方法我扩展方法是可以重载的,如

 class Room
{
public string Name { get; set; } public bool IsNull()
{
return this == null;
}
}

   在Room类中加一个实例方法IsNull,那当调用IsNul时,永远也调用不到扩展方法,记住上面说的"找方法"的顺序。

   请斧正。

18.C#扩展方法(十章10.1-10.2)的更多相关文章

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

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

  2. 为IEnumerable<T>添加RemoveAll<IEnumerable<T>>扩展方法--高性能篇

    最近写代码,遇到一个问题,微软基于List<T>自带的方法是public bool Remove(T item);,可是有时候我们可能会用到诸如RemoveAll<IEnumerab ...

  3. .NET中那些所谓的新语法之二:匿名类、匿名方法与扩展方法

    开篇:在上一篇中,我们了解了自动属性.隐式类型.自动初始化器等所谓的新语法,这一篇我们继续征程,看看匿名类.匿名方法以及常用的扩展方法.虽然,都是很常见的东西,但是未必我们都明白其中蕴含的奥妙.所以, ...

  4. 【开源】OSharp框架解说系列(3):扩展方法

    OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...

  5. c# 扩展方法奇思妙用基础篇八:Distinct 扩展(转载)

    转载地址:http://www.cnblogs.com/ldp615/archive/2011/08/01/distinct-entension.html 刚看了篇文章 <Linq的Distin ...

  6. ASP.Net MVC开发基础学习笔记(2):HtmlHelper与扩展方法

    一.一个功能强大的页面开发辅助类—HtmlHelper初步了解 1.1 有失必有得 在ASP.Net MVC中微软并没有提供类似服务器端控件那种开发方式,毕竟微软的MVC就是传统的请求处理响应的回归. ...

  7. 从扩展方法到匿名方法再到LINQ

    1.首先我们应该知道什么是扩展方法: 扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样 ...

  8. C# 扩展方法奇思妙用高级篇六:WinForm 控件选择器

    在Web开发中,jQuery提供了功能异常强大的$选择器来帮助我们获取页面上的对象.但在WinForm中,.Net似乎没有这样一个使用起来比较方便的选择器.好在我们有扩展方法,可以很方便的打造一个. ...

  9. C#语法糖: 扩展方法(常用)

    今天继续分享C#4.0语法糖的扩展方法,这个方法也是我本人比较喜欢的方法.大家先想想比如我们以前写的原始类型不能满足现在的需求,而需要在该类型中添加新的方法来实现时大家会怎么做.我先说一下我没有学习到 ...

随机推荐

  1. nyoj 38 布线问题

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=38 最小生成树水题~ 代码: #include "stdio.h" / ...

  2. 百度地图简单使用——添加折线,圆形等(html,js)

    地图覆盖物概述 所有叠加或覆盖到地图的内容,我们统称为地图覆盖物.如标注.矢量图形元素(包括:折线和多边形和圆).信息窗口等.覆盖物拥有自己的地理坐标,当您拖动或缩放地图时,它们会相应的移动. 地图A ...

  3. 解决在iOS8环境下,当用户关闭定位服务总开关时,无法将APP定位子选项加入定位权限列表的问题

    关键点:- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizati ...

  4. 如何用ZBrush确定头部五官的位置

    之前和大家讲过如何在ZBrush中确定头部雕刻,在第一阶段中面数很少,只能将大型体雕刻出来,由于面数太少不能进行下面的雕刻.接下来第二阶段的调整,需要重新分布模型表面的网格,增加面数,进行五官的位置的 ...

  5. unity3d Aniso Level 摄像机近地面清楚,远地面模糊

    设置方法 选中贴图 在属性面板,拖动Aniso Level的值从0~9改变,值越大贴图越清晰,但是消耗也变大,文档说会造成显卡消耗,一般只用在地面上,其他地方没必要 遇到的问题 但是打包到Ipod上面 ...

  6. AppScan8.0简单扫描

    上篇文章介绍了如何在WindowsXP中安装AppScan8.0,接着本篇就来说说怎么进行一次简单的扫描吧. AppScan8.0开始扫描 1.新建扫描,选择“常规扫描”,如下图: (常规.快速.综合 ...

  7. flex布局滑动页面

    html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  8. struts2验证框架1

    <!--该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts 2处理.如果用户需要指定多个请求后缀,则多个后缀之间以英文逗 ...

  9. C++引用和java引用的区别

    在c++里的引用其实是一个变量的别名,而java则是一个变量存储实际对象的地址和C++指针很相似

  10. WCF 异步调用问题

    添加引用时生成"勾选允许生成异步操作" Wcf异步调用三种方式: 第一种:直接调用异步方法 var serviceClient = new MyServiceClient(); s ...