首页 > 代码库 > 扩展方法简介

扩展方法简介

  以下是常规获取现在时间的一个方法。当有一天这个"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代表当前变量now11          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、扩展在父接口或父类上的扩展方法,在子类的实例中也可以调用

 

 



扩展方法简介