扩展方法简介

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

时间: 2024-10-03 21:53:37

扩展方法简介的相关文章

c#扩展方法简介

涂鸦一文,自娱娱乐. 无题 草舍如沙天地卷,且放白鹿青崖间.   望闻问切麻雀全,漫卷诗书彩云乡.   天地琴心天地曲,天际行将遥望远.   大浪淘沙鲁智深,乱云飞渡仍从容. c#扩展方法简介

ASP.Net MVC开发基础学习笔记(2):HtmlHelper与扩展方法

一.一个功能强大的页面开发辅助类—HtmlHelper初步了解 1.1 有失必有得 在ASP.Net MVC中微软并没有提供类似服务器端控件那种开发方式,毕竟微软的MVC就是传统的请求处理响应的回归.所以抛弃之前的那种事件响应的模型,抛弃服务器端控件也理所当然. 但是,如果手写Html标签效率又比较低,可重用度比较低.这时,我们该怎样来提高效率呢?首先,经过上篇我们知道可以通过ViewData传递数据,于是我们可以写出以下的Html代码: 1 <input name="UserName&q

扩展方法从简单应用到深入解析,读这一篇文章就够了

前言(扯淡-_-) 大家好,今天和大家聊聊扩展的事,我将带着大家从简单应用开始深入理解扩展方法的原理,并对扩展方法的使用给出合理的建议. 在实际应用中,当我们在使用某类时发现类中缺少我们想要的方法,最简单直接的就是修改类的源代码来添加我们想要的方法.但事实往往不如人意,总会因为各种因素不可以直接修改源码:拿不到源码.不允许修改,这时候通过继承并扩展的方式来复用是再好不过了,但是如果连最后的继承的权利都剥夺的话(密封类不允许继承)?...这时候就需要用到[扩展方法]了. 扩展方法简介 我们先来看看

C#学习笔记(八):扩展方法

还记得第一次使用DOTween时,发现缓动方法竟然是可以直接用Transform对象中调用到,当时就被震撼到了(那是还是C#小白一只).好了不多说了,今天来学习一下C#的这个特性——扩展方法. 扩展方法简介 扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 这样我们可以方便的扩展对象方法而无需使用继承,同时也可以给密封类添加方法. 我们来看一个例子: 1 using System; 2 3 namespace Study 4 { 5 class

ASP.Net MVC开发基础学习笔记:二、HtmlHelper与扩展方法

一.一个功能强大的页面开发辅助类—HtmlHelper初步了解 1.1 有失必有得 在ASP.Net MVC中微软并没有提供类似服务器端控件那种开发方式,毕竟微软的MVC就是传统的请求处理响应的回归.所以抛弃之前的那种事件响应的模型,抛弃服务器端控件也理所当然. 但是,如果手写Html标签效率又比较低,可重用度比较低.这时,我们该怎样来提高效率呢?首先,经过上篇我们知道可以通过ViewData传递数据,于是我们可以写出以下的Html代码: <input name="UserName&quo

C#-this关键字的功能之扩展方法

扩展方法 简介 我们的方法都是与声明他的类的相关联(我们现在写的各个方法都是在类中定义,所以我们调用方法都是用该方法所属类的实体对象调用). 在C#3.0中的扩展方法的特征,允许声明的方法与不是声明该方法的类相关联. 简单实例 下面我们定义了一个Person类,这个类有三个字段,和相应的三个属性 同时有一个方法 IntroductGender(). public class Person { public Person(string name, int age, string gender) {

C#基础知识---扩展方法

一.简介 扩展方法为现有的类型(.Net类型或者自定义类型)扩展应该附加到该类型中的方法. 二.基本原则 定义一个非嵌套.非泛型的静态类 扩展方法是静态的 扩展方法至少要有一个参数,该参数类型是要扩展的类型 第一个参数必须加上this关键字作为前缀 第一个参数不能用其他任何修饰符(如不能使用ref out等修饰符) 第一个参数的类型不能是指针类型 三.例子 例1:为.Net类型添加扩展方法 1 using System; 2 3 namespace ExtensionMethod 4 { 5 c

c# 扩展方法奇思妙用基础篇五:Dictionary&lt;TKey, TValue&gt; 扩展

Dictionary<TKey, TValue>类是常用的一个基础类,但用起来有时确不是很方便.本文逐一讨论,并使用扩展方法解决. 向字典中添加键和值 添加键和值使用 Add 方法,但很多时候,我们是不敢轻易添加的,因为 Dictionary<TKey, TValue>不允许重复,尝试添加重复的键时 Add 方法引发 ArgumentException. 大多时候,我们都会写成以下的样子: var dict = new Dictionary<int, string>()

C#3.0 扩展方法

扩展方法 在很多时候我们需要编写各种各样的帮助类,因为官方提供的再全面,也会有未包含到的地方,这时一个静态的帮助类就可以帮我们解决问题 举一个不是很恰当的例子,假如要对一个字符串进行验证其内容不为null并且等于admin但是很多地方都要调用,按照封装思想要封装成一个方法,看起来可能是下面这样子的 这并没有任何问题,代码也是比较简单,但是很难会有一种亲近感,因为StringiHelper.ValidArg这样的调用存在.比如这个验证应该是官方应该考虑到的,但是他们忽略了,编写这样一个扩展后会有很