扩展方法
1. 什么是扩展方法
首先我们来看看扩展方法到底是什么样子的:

我们定义了一个泛型集合list,我们看到很多方法有的带有一个向下的箭头,有的却没有,这些带箭头的方法就是扩展方法。
扩展方法可以再保持原有类型的基础上,对其进行扩展。扩展方法可以是同一程序中内方法的扩展,也可以是不同程序集的方法的扩展。有了扩展方法,我们就很容易对系统添加新的功能点,甚至对第三方的程序集进行扩展。
2. 自定义扩展方法
为了简单起见,假如有一个Person类,只有两个属性,没有任何方法
public class Person { public int Age { get; set; } public string Name { get; set; } }
我们对Person扩展一个方法
/// <summary> /// 对Person 类型进行扩展 /// </summary> public static class PersonExtension { public static void Show(this Person person) { Console.WriteLine("name={0},age={1}",person.Name,person.Age); } public static void PrintName(this Person person) { Console.WriteLine("我是扩展方法"); } }
客户端代码
static void Main(string[] args) { Person p = new Person(); p.Age = 24; p.Name = "wjw"; p.Show(); p.PrintName(); Console.ReadKey(); }
运行结果:
name=wjw,age=24
我是实例方法
3 本质分析
通过反编译代码如下;

可以看出来,IL代码中,扩展方法的第一个参数this没有了,这是因为这个this是给编译器用的,编译器会根据第一个被this修饰的关键字来对该类型进行扩展,但是这个语法,CLR在运行时并不知道,因此同时给该扩展方法添加一个ExtensionAttribute属性,表示这个一个扩展方法,以便在运行时CLR知道如何调用。
本质上来讲,扩展方法就是一个静态方法,其具有静态方法具有的一切功能。
我们来看看客户端调用代码发编译后的代码:

可看出
第一个扩展方法:p.PrintName();被编译成 PersonExtension::Show(class _06_扩展方法.Person) 这是调用扩展类中的扩展方法
第二个扩展方法:p.PrintName();被编译成:Person::PrintName()
3 结论
(1) 类中存在与扩展方法同名的方法,那么会先调用实例方法,即实例方法优于扩展方法
(2) 扩展方法必须是静态的,而且存在于静态非泛型的类中
4 注意
如果扩展的类的命名空间与类的命名空间不一致:有以下三种方法:
(1) 把命名空间改成一致
(2) 使用using 添加扩展类的命名空间
(3) 在web.config中添加扩展类的命名空间
浙公网安备 33010602011771号