C#3.0扩展方法(Extension Methods)

今天早上在MSDN站点看到这样一篇文章: C# 3.0 LINQ 的演变及其对 C# 设计的影响 。 从这篇文章我们就可以明显的看到,C# 3.0 所新增的这些特性,可以认为都是为了LINQ 的发展,为了LINQ更易用,所创建的一些新特性,当然这些新特性也可以被非LINQ相关功能所使用。LINQ的发展,带动了C#3.0 这一系列新特性的产生。

回来说我们的话题,扩展方法,首先看一个最简单的代码例子:

扩展方法的定义,需要注意三个部分:1、静态类(私有公共都可以);2、静态方法(私有公共都可以);3、第一个函数参数前带 this(必须是第一参数前)

namespace Hongjun.Guo
{
static class MyExtensionMethods
{
internal static void Print(this object s)
{
Console.WriteLine(s);
}
}
}

扩展方法的使用,需要注意点: using 你定义所在的命名空间。
using Hongjun.Guo;
static void Main(string[] args)
{
object o = "dsdgs";
o.Print();
}

这样一个简简单单的代码后,我们就可以很方便的对一些不开源的第三方控件增加很多我们自己额外需要的功能。

扩展方法的使用,有时候并不是这么简简单单,我们来看一些特殊情况,通过这些特殊情况的分析,我们可以更深入的了解扩展方法:

情况一 : 扩展方法跟原来类的方法重名时候的处理逻辑。
场景:我们是对一个第三方的没有开放源代码组件的一个类扩展了一个方法,比如方法: Print 。过了一段时间后,这个第三方的组件发布了新版本,该类的增加了 Print 方法。这时候会出何种效果??
问题演示代码:
namespace Hongjun.Guo
{ public class MyClass
{
public void Print()
{
Console.WriteLine("****");
}
} static class MyExtensionMethods
{
internal static void Print(this MyClass s)
{
Console.WriteLine("haha " + s.ToString());
} }
}
调用范例:
using Hongjun.Guo;
static void Main(string[] args)
{
MyClass o = new MyClass();
o.Print(); Console.ReadLine();
}

这时候我们会看到何种结果呢??

答案:看到的是 **** 也就是,扩展方法跟类的方法冲突时候,编译使用不会报任何错误,这时候以类的方法优先级最高,这时我们使用类的方法,而不是扩展方法。 分析: 我们把上述两组代码编译后,再反编译成IL,我们就可以看到,实际上,扩展方法在IL层上是不存在的。 扩展方法实际是编译器调用某个类的某个方法的时候,先去这个类找,如果有这个方法,则就调用;如果找不到,根据引用的命名空间,再去找扩展方法(静态类的静态方法)。找到,就使用,找不到当然就编译错误了。 根据这个分析结果,我们就可以理解上述问题处理的结果了。

情况二: 扩展方法的嵌套 比如我们有如下扩展方法。

namespace Hongjun.Guo
{
static class MyExtensionMethods
{
public static int Test01(this int i)
{
return i * 3;
} public static int Test02(this int i)
{
return i + 5;
}
}
}

下面是调用范例:

static void Main(string[] args)
{
int mm = 7;
Console.WriteLine(mm.Test01().Test02());
Console.WriteLine("*****");
Console.WriteLine(mm.Test02().Test01()); Console.WriteLine("*****");
Console.WriteLine(MyExtensionMethods.Test02(MyExtensionMethods.Test01(mm)));

Console.ReadLine();
}
问,调用的显示结果是何值?
答案: 依次显示: 26,36,26
分析: mm.Test01().Test02() 这行代码编译后相当于如下代码: MyExtensionMethods.Test02(MyExtensionMethods.Test01(mm)) 这两行代码在编译后的IL中是完全一样的。

时间: 2024-12-22 01:35:37

C#3.0扩展方法(Extension Methods)的相关文章

C#3.0 中使用扩展方法来扩展接口

有关扩展方法的一些知识点请参看我的前篇博客:C#3.0 中的扩展方法 (Extension Methods)前篇博客中我重点介绍了两个特殊场景:1.扩展方法跟原来类的方法重名时候的处理逻辑2.扩展方法的嵌套现在我们来看扩展方法使用的第三个场景:使用扩展方法来扩展接口 应用场景举例:我们有时候会发现最初定义的一个接口,在现在环境下,这个接口需要再增加一个函数.有了扩展方法后,我们在这种情况下又多了一种实现的选择.下面以代码来说明这个问题:namespace Hongjun.Guo{interfac

C# 3.0语言新特性(语言规范):2 扩展方法

规范 原文:<C# Version 3.0 Specification>,Microsoft翻译:lover_P 扩展方法(Extension Methods)是一种静态方法,可以通过实例方法的语法进行调用.从最终效果上看,扩展方法使得扩展一个现有类型和构造一个具有附加方法的类型变成了现实. 注意 扩展方法很难发觉,并且比起实例方法在功能性上有很大限制.出于这些原因,我们建议保守地使用扩展方法,仅在实例方法不大可行或根本不可行的时候才使用. 扩展成员的其他类型,如属性.事件和运算符都在考虑之中

《圣殿祭司的ASP.NET4.0专家技术手册》----2-12 扩展方法

2-12 扩展方法 圣殿祭司的ASP.NET4.0专家技术手册 扩展方法(Extension Methods)允许针对现有类型加入自定义方法,而不必用传统方式,先继承然后再实现方法,最后还要再进行编译,完全省略了这些不必要的步骤. 然而,什么时候需使用到扩展方法?通常有两个时机: (1)需扩展类型额外的方法,就可通过扩展方法加入额外的方法: (2)希望直接使用系统已建立好的扩展方法,这种情况在LINQ中尤其明显. 范例2-12 使用扩展方法扩展string类型方法 假设要将阿拉伯数字"2266&

C# 3.0新特性初步研究 Part2:使用扩展方法

扩展方法(Extension Method)可以为已有的类型添加新的方法定义和实现,比如int类型目前没有一个名叫xxxyyy()的方法,那么通过使用扩展方法,我们可以为int类型添加一个xxxyyy()方法.这个有点类似于用来扩展系统功能的某些设计模式. 下面我们用代码来说话:这是我们以前的写法:    1public static class Extensions 2{ 3    public static string CamelCase(string identifier) 4{ 5  

asp.net C# 3.0 新特性 学习(二):匿名类型、扩展方法

这两天看了一下msdnwebcast上的visual studio 2008的系列课程,记录下所学的知识,以便加深记忆 1.匿名类型 顾名思义 匿名类型就是没有名字的类型.在C#3.0中允许我们在程序中声明一个临时的类型来存储数据,例如:    代码如下 复制代码 class Program      {          static void Main(string[] args)          {              //声明一个匿名对象,拥有 Name和Age 属性      

C# 3.0 新特性:扩展方法初探

C#3.0中一个激动人心的特性就是扩展方法:你可以使用实例方法的语法来调用静态方法.本文仔细阐述了这一新特性并且给出了几个相应的例子. 声明扩展方法 扩展方法的行为和静态方法是非常类似的,你只能在静态类中声明它们.为声明一个扩展方法,你需要给该方法的第一个参数指定this关键字,如下例: // Program.cspublic static class EMClass{ public static int ToInt32Ext(this string s) { return Int32.Pars

了解c#2.0中的Anonymous Methods(匿名方法)

  Anonymous Methods 是 C#2.0的新特性之一,它允许我们在代码中创建一个内置的没有方法名的方法,将代码与委托实例相关联,从而使委托的实例化工作更加直观和方便,提高了代码的可读性和可维护性.下面来看一个简单的匿名方法的使用: private int[] _integers =      { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int[] evenIntegers = Array.FindAll(_integers,                 

C#3.0笔记(三)var关键字与扩展方法

从这篇blog开始真正开始关心3.0里面的特性,本篇主要介绍下Var关键字与 扩展方法. 初识var关键字 C#3.0中为我们提供了var关键字来定 义隐式化的局部变量,定义方式: var i = 0; var myBool = true; var myString = "Henllyee"; 其实在使用var关键字时,编译器会根据 初始化变量的变量值来推断变量的数据类型,我们可以通过IL来看下上面几句代 码在编译之后的表示: .locals init ([0] int32 i, [1

C# 3.0 新特性----扩展方法

转自 http://www.cnblogs.com/jiejie_peng/archive/2010/04/08/1707195.html C# 3.0 新特性----扩展方法 主要目的掌握对一个已经编译的类的方法的扩展 特别注意a. 扩展某个类时,新建的类要使用 public static 修饰,因为默认的类是 internal 访问修饰符b. 这个类要有文件作用域,即不能作为嵌套类使用c. 扩展方法要声明为静态的d. 扩展方法的第一个参数类型即是要扩展的类,且该参数前要加 this 关键字e