zoukankan      html  css  js  c++  java
  • 扩展方法简介

      以下是常规获取现在时间的一个方法。当有一天这个"yyyy-MM-dd"格式,有个需求需要在一千个方法中实现,你确定要写上一千次?不会吧!于是得想办法格式化一次便能达到目的。

     1         /// <summary>
     2         /// 静态方法,便于在Main函数中调用.
     3         /// </summary>
     4         static void ExtMethod()
     5         {
     6             DateTime now = DateTime.Now;
     7             // 时间格式 年-月-日
     8             string yyyymmddFmt = now.ToString("yyyy-MM-dd");
     9             Console.WriteLine(yyyymmddFmt);
    10         }    

          你会想到写一个静态类,静态方法。于是马不停蹄的新建类··· 新建方法···

     1  /// <summary>
     2     /// 静态类,静态方法
     3     /// </summary>
     4     public static class ExtMehtodHelp
     5     {
     6         public static string FmtYYYYMMDD(DateTime date)
     7         {
     8             // 返回时间
     9             return date.ToString("yyyy-MM-dd");
    10         }
    11     } 

       然后在ExtMethod()方法中,便可以通过静态类点出静态方法。然后你在这一千个方法中都调用了这个静态方法。

     1         /// <summary>
     2         /// 静态方法,便于在Main函数中调用.
     3         /// </summary>
     4         static void ExtMethod()
     5         {
     6             DateTime now = DateTime.Now;
     7             // 时间格式 年-月-日
     8             string yyyymmddFmt = now.ToString("yyyy-MM-dd");
     9             // 调用静态类中的静态方法
    10             string fmt01 = ExtMehtodHelp.FmtYYYYMMDD(now);
    11 
    12             Console.WriteLine(fmt01);
    13         }    

      静态类点出静态方法,确是无可厚非的。

      如果有一种更简单的方法通过 DateTime 的 now 变量直接点出方法 FmtYYYYMMDD 的话。那多好哇,类名都用不着记了!

    也可以认为 now 是一个实例,想要在实例上点出方法,那么必须是实例方法。而DateTime是微软封装好的代码,我们无法改动,所以

    无法往类里面添加方法。然而现在又有这么一个需求,所以提供了一种方法叫做扩展方法。   

     1      /// <summary>
     2      /// 扩展方法的必要条件
     3      /// 1、此方法必须是一个静态方法
     4      /// 2、此方法必须放到静态类中
     5      /// 3、方法的第一个参数要以this开头,后面跟着此扩展方法所在的类型参数
     6      /// </summary>   
     7      public static class ExtMehtodHelp
     8      {
     9          // 谁点出此方法就要在其类型前加this 
    10          // DateTime有个形参,表示此方法扩展至DateTime。date代表当前变量now
    11          public static string FmtYYYYMMDD(this DateTime date)
    12          {
    13              return date.ToString("yyyy-MM-dd");
    14          }
    15      }

      于是在调用的时候就可以直接通过 now.FmtYYYYMMDD 来获取。在now点方法的时候,FmtYYYYMMDD方法前面是有一个向下的箭头,表示此为扩展方法。

     1         /// <summary>
     2         /// 静态方法,便于在Main函数中调用.
     3         /// </summary>
     4         static void ExtMethod()
     5         {
     6             DateTime now = DateTime.Now;
     7             // 普通形式 时间格式 年-月-日
     8             string yyyymmddFmt = now.ToString("yyyy-MM-dd");
     9             // 调用静态类中的静态方法
    10             string yyyymmddFmt01 = ExtMehtodHelp.FmtYYYYMMDD(now);
    11             // 调用扩展方法
    12             string yyyymmddFmt02 = now.FmtYYYYMMDD();
    13 
    14             Console.WriteLine(yyyymmddFmt02);
    15         }

      给扩展方法加多一个参数,这便是扩展方法的真正参数

     1      /// <summary>
     2      /// 扩展方法的另外一个参数,才是他的真正参数
     3      /// </summary>   
     4      public static class ExtMehtodHelp
     5      {
     6          public static string FmtYYYYMMDD(this DateTime date,string str)
     7          {
     8              return date.ToString("yyyy-MM-dd");
     9          }
    10  
    11      }
     1         /// <summary>
     2         /// 静态方法,便于在Main函数中调用.
     3         /// </summary>
     4         static void ExtMethod()
     5         {
     6             DateTime now = DateTime.Now;
     7             // 普通形式 时间格式 年-月-日
     8             string yyyymmddFmt = now.ToString("yyyy-MM-dd");
     9             // 调用静态类中的静态方法
    10             //string yyyymmddFmt01 = ExtMehtodHelp.FmtYYYYMMDD(now);
    11             // 调用扩展方法
    12             // 这才是扩展方法的真正参数
    13             string yyyymmddFmt02 = now.FmtYYYYMMDD("Hello");
    14 
    15             Console.WriteLine(yyyymmddFmt02);
    16         }

      总结:通过反编译工具可看出,扩展方法其本质是静态方法。编译器认为一个表达方式是要使用一个实例方法,但是没有找到,就会检查导入的命名空间和当前命名空间里所有的扩展方法,并匹配适合的方法

    .method private hidebysig static void ExtMethod() cil managed
    {
        .maxstack 2
        .locals init (
            [0] valuetype [mscorlib]System.DateTime time,
            [1] string str)
        L_0000: nop 
        L_0001: call valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now()
        L_0006: stloc.0 
        L_0007: ldloc.0 
        L_0008: ldstr "Hello"
        L_000d: call string D03_01新语法.ExtMehtodHelp::FmtYYYYMMDD(valuetype [mscorlib]System.DateTime, string)
        L_0012: stloc.1 
        L_0013: ldloc.1 
        L_0014: call void [mscorlib]System.Console::WriteLine(string)
        L_0019: nop 
        L_001a: ret 
    }

      扩展方法的必要条件
    1、此方法必须是一个静态方法
    2、此方法必须放到静态类中
    3、方法的第一个参数要以this开头,后面跟着此扩展方法所在的类型参数
      特点:(这里没有演示)
    1、扩展方法与实例方法可以构造成重载
    2、如果扩展方法的名称和参数与实例方法相同,则实例方法的优先级高于扩展方法来调用
    3、扩展在父接口或父类上的扩展方法,在子类的实例中也可以调用



  • 相关阅读:
    权限、角色及架构 【转载】
    C#和SQL SERVER 实用工具推荐 『转载』
    创建自定义配置节点(web.config和app.config都适用)【转载】
    asp.net代码中尖括号和百分号的含义 <转载>
    为JavaScript程序添加客户端不可见的注释 【转载】
    C#中string[]数组和list<string>泛型的相互转换 【转】
    程序员从初级到中级10个秘诀 【转载】
    PowerDesigner 使用教程 【转载】
    【openstack N版】——网络服务neutron(flat扁平网络)
    【openstack N版】——镜像服务glance
  • 原文地址:https://www.cnblogs.com/lucklongwen/p/4018202.html
Copyright © 2011-2022 走看看