18.C#扩展方法(十章10.1-10.2)
今天的话题,我们来聊下扩展方法,自己也真心感叹自己的文笔,那叫一个惨啊,回顾写的文章,看着看着也忘记当时是怀着什么心态写的,哈哈,现代人真心是太随性了,可能也是太冷漠了,接着写的吧,总是会有帮助,也会有收获的。
扩展方法是从C#3开始出现在我们的眼前,它即有静态方法的优点,也使我们的代码更具可读性,可以像实例方法一样调用静态方法。在扩展方法没有出现前,我们在代码中常常出现静态的工具类(当然,即使现在我们来会使用静态工具类,那都是前人的智慧结晶),如一个字符串帮助类、时间转换工具类。想像一下,当我们得到一个封装好的类库,里面的源代码是不可见,我们只是类库的使用者,但类库的开发者也不是十全十美的思路,总是会有一些遗漏。我们拿简单的来说,比如现在我拿到一份代码,代码中有一个Room类,如下:
1 class Room 2 { 3 public string Name { get; set; } 4 }
上面的代码是不能修改的,想象一个我们可以使用什么方法给对象的Name属性赋值?我们可以使用实例一个Room对象,直接赋值,但现在我想给Room类加一个SetName的方法,那扩展方法会帮助到我们。如:
1 static class RoomExt 2 { 3 public static void SetName(this Room room, string name) 4 { 5 room.Name = name; 6 } 7 } 8 9 Room room = new Room(); 10 room.Name = "草堂"; 11 Console.WriteLine(room.Name); 12 room.SetName("澡堂"); 13 Console.WriteLine(room.Name); 14 Console.ReadKey();
上述代码中,SetName方法就是Room类的扩展方法,可以像调用实例方法一样调用它。Room类的开发者忘记给Room类增加一个SetName方法,那我们就使用扩展方法给Room类加一个方法,调用的方式和实例方法一样。SetName的第一个参数为扩展类型,指定要扩展的类,并使用关键字this,规定而已,请遵守之。方法的修饰符为static,呵呵,遵守之。如果我们写的代码是外部调用的话,请使用public关键字,使用pirvate关键字,那就只能在为其扩展的扩展方法中才能使用。
1 room.SetName("澡堂"); //调用SetName方法,内部会实现为RoomExt.setName(room,"澡堂")
上面的代码是不是和我们的静态工具一样,是的,使用扩展方法,可以使用代码更具可读性。当然上述的代码只是一个简单使用,在我们正常使用中,自己写的类肯定会加入合适的实例方法,即使是类库的,那也会让类库开发者加一个方法。但如果是微软的开发者没给出合适的方法,没办法,自己加吧。所以扩展方法经常被我们用来扩展系统类型的方法。扩展方法类似静态方法,但它也必须要具有以下的特征:
- 它必须在一个非嵌套的、非泛型的静态类中,如RoomExt类
- 它至少要有一个参数
- 第一个参数不能使用其它修饰符(ref和out)
- 第一个参数必须使用this关键字修饰
- 第一个参数的类型不能是指针类型
找到合适的方法
当我们使用SetName时,会先在实例方法中找,是否有这个方法,如果没有,会从引入的命名空间中找签名符合的方法,也有可能全有重载情况发生,那基于"谁更优"找到方法并执行。
对空类型进行扩展
实际上是对object对象进行扩展,如
1 static class objectExt 2 { 3 public static bool IsNull(this object o) 4 { 5 return o == null; 6 } 7 }
使用如下:
1 static class objectExt 2 { 3 public static bool IsNull(this object o) 4 { 5 return o == null; 6 } 7 } 8 9 10 Room room1 = null; 11 Console.WriteLine(room1.IsNull());
使用是不是很生动,如果你愿意也可以在类中加一个实例方法IsNull,或者使用静态工具来判断一个实例是否为null。实例方法我扩展方法是可以重载的,如
1 class Room 2 { 3 public string Name { get; set; } 4 5 public bool IsNull() 6 { 7 return this == null; 8 } 9 }
在Room类中加一个实例方法IsNull,那当调用IsNul时,永远也调用不到扩展方法,记住上面说的"找方法"的顺序。
请斧正。