zoukankan      html  css  js  c++  java
  • 3. Extension Methods(扩展方法)

    【返回目录】

    什么是扩展方法?简而言之,扩展方法是一种开发人员轻松快捷地扩展已有类型的方法定义和实现的机制。具体一点儿讲,首先,扩展方法必须是静态方法,从语法的层面来看它的调用和实例方法没有什么区别,我们还是看码说话吧:

       1: public static class ExtensionMethodDemo
       2: {
       3:     public static decimal ToMoney(this string money)
       4:     {
       5:         decimal number = 0m;
       6:  
       7:         if (!decimal.TryParse(money, out number))
       8:         {
       9:             throw new ArgumentException("Money Error Information.");
      10:         }
      11:  
      12:         return number;
      13:     }
      14:  
      15:     public static int ToAge(this string age)
      16:     {
      17:         int number = 0;
      18:  
      19:         if (!int.TryParse(age, out number))
      20:         {
      21:             throw new ArgumentException("Age Error Information.");
      22:         }
      23:  
      24:         return number;
      25:     }
      26: }

    这段代码的作用是扩展string类型,使其拥有直接将string类型转换成decimal或int类型的方法,调用方法如下:

       1: static void Main(string[] args)
       2: {
       3:     string moneyInput = Console.ReadLine();
       4:  
       5:     decimal money = moneyInput.ToMoney();
       6:     int age = "24".ToAge();
       7:  
       8:     // TODO: Do something...
       9: }

    不难看出,我们很轻松地就为字符串增加了两个可能在实际项目中常常需要用到的方法,同时扩展方法还传承了C#简洁高雅的语法传统,接下来我们来仔细研究一下上面的这两段代码吧。

    如前所示,扩展方法必须是静态的,因此static关键字是少不了的,扩展方法只能在非泛型或非嵌套的静态类中声明,它是通过关键字this作为其第一个参数的修饰符来声明,它的第一个参数除了this关键字以外可以没有别的修饰符,同时这个参数不能是指针类型。扩展方法具备和常规静态方法一样的能力,我们不妨来看一个复杂一点儿的扩展方法:

       1: namespace DevLab
       2: {
       3:     class Program
       4:     {
       5:         static void Main(string[] args)
       6:         {
       7:             string[] names = new string[] { "ZeroCool", "Michael", "Autumoon" };
       8:             string[] nameRange = names.Range(0, 2);
       9:  
      10:             var ages = new int[] { 1, 2, 3, 4 };
      11:             var ageRange = ages.Range(1, 2);
      12:  
      13:             // TODO: Do something...
      14:         }
      15:     }
      16:  
      17:     public static class ExtensionMethodDemo
      18:     {
      19:         public static T[] Range<T>(this T[] original, int startIndex, int count)
      20:         {
      21:             if (startIndex < 0 || count < 0 || startIndex > original.Length)
      22:             {
      23:                 throw new ArgumentException("Argument Error Information.");
      24:             }
      25:  
      26:             T[] result = new T[count];
      27:             Array.Copy(original, startIndex, result, 0, count);
      28:  
      29:             return result;
      30:         }
      31:     }
      32: }

    通过上面这段代码,大家可以看到扩展方法这套机制的强大之处了吧。

    另外,我们需要注意的是,实例方法要优先于扩展方法的调用,在命名空间内声明的扩展方法要优先于命名空间外声明的扩展方法的调用;并且,由于就功能性而言,扩展方法相比实例方法更不明显且具有更多的限制,所以微软官方推荐大家谨慎适用扩展方法,最好只在实例方法不可行的情况下使用。最后,扩展方法目前还不支持属性、事件和操作符等类型。

  • 相关阅读:
    服务注册发现Eureka之二:高可用服务注册中心
    可重入锁 公平锁 读写锁、CLH队列、CLH队列锁、自旋锁、排队自旋锁、MCS锁、CLH锁
    红黑树(Red-Black tree)
    fuser 命令小结
    客户端负载均衡Ribbon之三:AvailabilityFilteringRule的坑(Spring Cloud Finchley.SR2)
    mysql重复记录的查询删除方法
    innodb的锁、update单条记录的花费时间压测
    被kill问题之1:进程物理内存远大于Xmx的问题分析
    服务注册发现Eureka之三:Spring Cloud Ribbon实现客户端负载均衡(客户端负载均衡Ribbon之三:使用Ribbon实现客户端的均衡负载)
    十二、jdk工具之jcmd介绍(堆转储、堆分析、获取系统信息、查看堆外内存)
  • 原文地址:https://www.cnblogs.com/Autumoon/p/961098.html
Copyright © 2011-2022 走看看