• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > C#中的扩展方法详解

C#中的扩展方法详解

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c#网站开发案例详解,c#基础与案例开发详解,c#泛型详解,c#关键字详解,c#三层架构详解等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。 以上是msdn官网对扩展方法的描述,现在我通过一个情景例子来对此进行阐释。假设一个控制台程序class Program{}里面的主函数如下:

static void Main(string[] args)
    {
      DateTime now = DateTime.Now;
      string time = now.ToString("yyyy-mm-dd hh:mm:ss"); 
      Console.WriteLine(time);
      Console.ReadKey();
    }
</div>

假设需求变了,日期的显示格式要变成"yyyy-mm-dd"这种格式,当然只需要初始化time时按下面写法改写即可:

string time = now.ToString("yyyy-mm-dd");
但是如果要改变日期格式的有很多个类呢?每个都要改一次吗?这样一旦需求变来变去就忙死人了。传统的解决方式是封装一个帮助类,在里面写方法,然后供其他类调用。

本例在当前项目模仿添加一个DateHelper类:public class DateHelper{},在类里面定义方法:

public static string DateToString(DateTime dt)
    {
      return dt.ToString("yyyy-mm-dd hh:mm:ss");
    }
</div>

于是原来的主函数改写如下:

static void Main(string[] args)
    {
      DateTime now = DateTime.Now;
      string time = DateHelper.DateToString(now);
      Console.WriteLine(time);
      Console.ReadKey();
    }
</div>

此时如果变需求,只需要改写DateHelp类里的DateToString()方法就行了,不管有多少个类调用此方法,都会被影响。问题解决了,可是这样要调用另一个类的方法,还是有点麻烦,有没有什么方法能够让我们像now.DateToString()一样直接调用呢?当然DateTime是微软写好的,我们改不了,无法创建想要的实例方法,于是,便引出了扩展方法。
下面是扩展方法的要素:

1.此方法必须是一个静态方法

2.此方法必须放在静态类中

3.此方法的第一个参数必须以this开头,并且指定此方法是扩展自哪个类型

根据以上要素,我们DateHelper类改成静态类:public static class DateHelper{} ,同时改写DateToString()方法:

public static string DateToString(this DateTime dt)
    {
      return dt.ToString("yyyy-mm-dd hh:mm:ss");
    }
</div>

此时回到主函数方法体,输入"now."便可以看见自动提示有个DateToString()方法,于是代码可以这样写:

static void Main(string[] args)
    {
      DateTime now = DateTime.Now; 
      string time = now.DateToString();
      Console.WriteLine(time);
      Console.ReadKey();
    }
</div>

显而易见,这样用起来会更加便捷,而且这样让我们看起来确实就像是被扩展类型本身具有的实例方法一样,可读性很高。下面概括一下扩展方法的特点:

1.扩展方法扩展自哪个类型,就必须是此类型的变量来使用,其他类型无法使用,本例扩展自DateTime类型,就只能是被DateTime类型的变量.出来(now.DateToString())
2.扩展方法中的this后面的参数不属于方法的参数,本例是无参数,this后面的DateTime dt是指明扩展方法扩展自何种类型
3.如果扩展方法和实例方法具有相同的签名,则优先调用实例方法
4.扩展自父类上的方法,可以被子类的对象直接使用
5.扩展自接口上的方法,可以被实现类的对象直接使用
6.扩展方法最终还是被编译器编译成:静态类.静态方法(),本例中now.DateToString()最终还是会被编译成DateHelper.DateToString(now),这是它的本质

实际上,我们可能会遇到这样的情景,如在接口扩展一个方法的时候,所有的原本已实现该接口的类都要实现新扩展的方法,这样的改动是一个很麻烦的工作,可以使用扩展方法“曲线救国”;而有时候我们想为某个类添加新方法却不想改动这个类,那么扩展方法这种“伪添加”方法的方式就体现出它的价值了。最常见的扩展方法是LINQ标准查询运算符,运用广泛,这种方便快捷的方式理应博得码农们点1024个赞。

“扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。”

这是msdn上说的,也就是你可以对String,Int,DataRow,DataTable等这些类型的基础上增加一个或多个方法,使用时不需要去修改或编译类型本身的代码。

先做个例子吧,以String为例,需要在字符串类型中加一个从字符串转为数值的功能。

以往我们可能是这样做的,会专门写一个方法做过转换

public static int StrToInt(string s)
{
  int id;
  int.TryParse(s, out id);//这里当转换失败时返回的id为0
  return id;
}
</div>

调用就使用

string s = "abc";
int i = StrToInt(s);
</div>

若是String类型有一个名为ToInt()(从字符串转为数值)的方法,就可以这样调用了

string s = "abc";
int i = s.ToInt();
</div>

这样看起来是不是更好,下面来看看具体怎么实现吧

第一步:

我先创建一个解决方案,一个web应用程序(webtest)及一个类库(W.Common)

在webtest项目添加引用W.Common项目

第二步:在类库中新建一个名为EString.cs类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace W.Common
{
  public static class EString
  {
    /// <summary>
    /// 将字符串转换为Int
    /// </summary>
    /// <param name="t"></param>
    /// <returns>当转换失败时返回0</returns>
    public static int ToInt(this string t)
    {
      int id;
      int.TryParse(t, out id);//这里当转换失败时返回的id为0
      return id;
    }
  }
}
</div>


看了上面的代码了吧,扩展方法规定类必须是一个静态类,EString是一个静态类,里面包含的所有方法都必须是静态方法。

msdn是这样规定扩展方法的:“扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的。 它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。”

EString里有一个ToInt的静态方法,他接收一个自身参数this,类型为string,this string必须在方法参数的第一个位置。

这句话什么意思,即你需要对string扩展一个ToInt方法,this是string实例化后的对象,这可能说的不太清楚,我的表述能力能弱,不要见怪呀。。。通俗的说就是,扩展方法跟静态类的名称无关,只需要在一个静态类里面定义一个静态方法,第一个参数必须this string开头。

如果需要你要对DateTime类型扩展方法名为IsRange(判断是否在此时间范围内),代码如下:

/// <summary>
  /// 此时间是否在此范围内 -1:小于开始时间 0:在开始与结束时间范围内 1:已超出结束时间
  /// </summary>
  /// <param name="t"></param>
  /// <param name="startTime"></param>
  /// <param name="endTime"></param>
  /// <returns></returns>
  public static int IsRange(this DateTime t, DateTime startTime, DateTime endTime)
  {
    if (((startTime - t).TotalSeconds > 0))
    {
      return -1;
    }
 
    if (((endTime - t).TotalSeconds < 0))
    {
      return 1;
    }
 
    return 0;
  }
</div>


这里的扩展方法是用this DateTime打头,那么就可以这样调用

time.IsRange(t1,t2);//判断时间time是否在t1到t2的范围内
当前代码在使用扩展方法前需要先引用命名空间

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using W.Common;//这里引用扩展方法所在的命名空间
 
namespace webtest
{
  public partial class _Default : System.Web.UI.Page
  {
    protected void Page_Load(object sender, EventArgs e)
    {
      use1();
      Response.Write("<br />");
      use2();
    }
 
    /// <summary>
    /// 没有用扩



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C#给Excel添加水印实例详解
  • C#枚举类型和结构体详解
  • C#调用Java方法实例详解
  • C#获取机器码的方法详解(机器名,CPU编号,硬盘编号,网卡mac等)
  • C#同步网络时间的方法实例详解
  • C#中的预处理器指令详解
  • C#的FileSystemWatcher用法实例详解
  • C#中常见的系统内置委托用法详解
  • C#中的扩展方法详解
  • 基于C#实现的木马程序实例详解

相关文章

  • 2017-05-28算法练习之从String.indexOf的模拟实现开始
  • 2017-05-28C#在RichTextBox中显示不同颜色文字的方法
  • 2017-05-28C#实现程序开机启动的方法
  • 2017-05-28C#实现自定义windows系统日志的方法
  • 2017-05-28winform下实现win7 Aero磨砂效果实现代码
  • 2017-05-28C#实现毫秒转换成时分秒的方法
  • 2017-05-28C#中的is和as操作符区别小结
  • 2017-05-28C#实现打印与打印预览功能的思路及代码
  • 2017-11-28C#数据库的修改
  • 2017-05-28C# DoubleClick与MouseDoubleClick区别,双击事件引发顺序

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C#常用的命名规则汇总
    • C#生成PDF文件流
    • 谈一谈autofac组件的实例范围
    • C#获取文件相关信息的方法
    • C#判断字符串是否是int/double(实例)
    • C#中DataTable 转实体实例详解
    • C#生成条形码图片的简单方法
    • C#开发的人脸左右相似度计算软件源码分析
    • C#方法的总结详解
    • C#中抽象类与接口的区别详解

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有