18.C#扩展方法(十章10.1-10.2)
今天的话题,我们来聊下扩展方法,自己也真心感叹自己的文笔,那叫一个惨啊,回顾写的文章,看着看着也忘记当时是怀着什么心态写的,哈哈,现代人真心是太随性了,可能也是太冷漠了,接着写的吧,总是会有帮助,也会有收获的。
扩展方法是从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,"澡堂")
上面的代码是不是和我们的静态工具一样,是的,使用扩展方法,可以使用代码更具可读性。当然上述的代码只是一个简单使用,在我们正常使用中,自己写的类肯定会加入合适的实例方法,即使是类库的,那也会让类库开发者加一个方法。但如果是微软的开发者没给出合适的方法,没办法,自己加吧。所以扩展方法经常被我们用来扩展系统类型的方法。扩展方法类似静态方法,但它也必须要具有以下的特征:
- 它必须在一个非嵌套的、非泛型的静态类中,如RoomExt类
- 它至少要有一个参数
- 第一个参数不能使用其它修饰符(ref和out)
- 第一个参数必须使用this关键字修饰
- 第一个参数的类型不能是指针类型
找到合适的方法
当我们使用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)的更多相关文章
- 19.C#逐一介绍IEnumerable和IEnumerable<T>中的扩展方法(10.3-10.5)
今天没有太多的言语,只有代码,扩展方法多得太多,不能一一列完,书中一些,看多了也就会使用了. //Enumerable.Range 返回起始到结束范围,是一个Enumrable<int>类 ...
- 为IEnumerable<T>添加RemoveAll<IEnumerable<T>>扩展方法--高性能篇
最近写代码,遇到一个问题,微软基于List<T>自带的方法是public bool Remove(T item);,可是有时候我们可能会用到诸如RemoveAll<IEnumerab ...
- .NET中那些所谓的新语法之二:匿名类、匿名方法与扩展方法
开篇:在上一篇中,我们了解了自动属性.隐式类型.自动初始化器等所谓的新语法,这一篇我们继续征程,看看匿名类.匿名方法以及常用的扩展方法.虽然,都是很常见的东西,但是未必我们都明白其中蕴含的奥妙.所以, ...
- 【开源】OSharp框架解说系列(3):扩展方法
OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...
- c# 扩展方法奇思妙用基础篇八:Distinct 扩展(转载)
转载地址:http://www.cnblogs.com/ldp615/archive/2011/08/01/distinct-entension.html 刚看了篇文章 <Linq的Distin ...
- ASP.Net MVC开发基础学习笔记(2):HtmlHelper与扩展方法
一.一个功能强大的页面开发辅助类—HtmlHelper初步了解 1.1 有失必有得 在ASP.Net MVC中微软并没有提供类似服务器端控件那种开发方式,毕竟微软的MVC就是传统的请求处理响应的回归. ...
- 从扩展方法到匿名方法再到LINQ
1.首先我们应该知道什么是扩展方法: 扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样 ...
- C# 扩展方法奇思妙用高级篇六:WinForm 控件选择器
在Web开发中,jQuery提供了功能异常强大的$选择器来帮助我们获取页面上的对象.但在WinForm中,.Net似乎没有这样一个使用起来比较方便的选择器.好在我们有扩展方法,可以很方便的打造一个. ...
- C#语法糖: 扩展方法(常用)
今天继续分享C#4.0语法糖的扩展方法,这个方法也是我本人比较喜欢的方法.大家先想想比如我们以前写的原始类型不能满足现在的需求,而需要在该类型中添加新的方法来实现时大家会怎么做.我先说一下我没有学习到 ...
随机推荐
- nyoj 38 布线问题
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=38 最小生成树水题~ 代码: #include "stdio.h" / ...
- 百度地图简单使用——添加折线,圆形等(html,js)
地图覆盖物概述 所有叠加或覆盖到地图的内容,我们统称为地图覆盖物.如标注.矢量图形元素(包括:折线和多边形和圆).信息窗口等.覆盖物拥有自己的地理坐标,当您拖动或缩放地图时,它们会相应的移动. 地图A ...
- 解决在iOS8环境下,当用户关闭定位服务总开关时,无法将APP定位子选项加入定位权限列表的问题
关键点:- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizati ...
- 如何用ZBrush确定头部五官的位置
之前和大家讲过如何在ZBrush中确定头部雕刻,在第一阶段中面数很少,只能将大型体雕刻出来,由于面数太少不能进行下面的雕刻.接下来第二阶段的调整,需要重新分布模型表面的网格,增加面数,进行五官的位置的 ...
- unity3d Aniso Level 摄像机近地面清楚,远地面模糊
设置方法 选中贴图 在属性面板,拖动Aniso Level的值从0~9改变,值越大贴图越清晰,但是消耗也变大,文档说会造成显卡消耗,一般只用在地面上,其他地方没必要 遇到的问题 但是打包到Ipod上面 ...
- AppScan8.0简单扫描
上篇文章介绍了如何在WindowsXP中安装AppScan8.0,接着本篇就来说说怎么进行一次简单的扫描吧. AppScan8.0开始扫描 1.新建扫描,选择“常规扫描”,如下图: (常规.快速.综合 ...
- flex布局滑动页面
html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- struts2验证框架1
<!--该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts 2处理.如果用户需要指定多个请求后缀,则多个后缀之间以英文逗 ...
- C++引用和java引用的区别
在c++里的引用其实是一个变量的别名,而java则是一个变量存储实际对象的地址和C++指针很相似
- WCF 异步调用问题
添加引用时生成"勾选允许生成异步操作" Wcf异步调用三种方式: 第一种:直接调用异步方法 var serviceClient = new MyServiceClient(); s ...