从C# 3.0说以人为本(三)—— 扩展方法

2023-05-16

 说完了LINQ的语言支持和语法灵活,下面就是一个非常有用的东东——扩展方法(Extension Method)。

 

还记得我们看了好几遍的LINQ吧,下面这个:

  1.     var numQuery =
  2.     from num in numbers
  3.     where (num % 2) == 0
  4.     select num;

第一次讨论的时候我们讲到它等同于:

  1. IEnumerable<int> numQuery = numbers.Where((number) => number % 2 == 0);

 

如果用2.0很熟悉的朋友,会知道Where函数是3.0新增的,同时新增的还有Sum,Count等一系列方法,在MSDN 2008中,我们可以看到这些函数归属于IEnumerable<T>泛型接口成员,同时,他们都属于一个新的方法类型称为扩展方法,新的小图标是一个原来的方法图标边上加入一个向下的小箭头

我们暂且先不讨论这个,先看看Array,List<T>类,它们都扩展了IEnumerable<T>,同时就具有了这些新增的方法。但是,这些方法是全部通过扩展接口重载了吗?好象不像,因为这些方法都大同小异,如果真的是用每个类重载实现的,代码的重复量就未免太大了。而且,如果是通过扩展接口实现的,又如何能称为“扩展方法”呢?

我们再仔细看看MSDN,在每个IEnumerable<T>泛型接口扩展方法的后面,都有一个解释:(由 Enumerable 定义。)。越来越奇怪了!一个接口的方法由另外一个类定义?!这是什么东西?怎么由一个类定义一个接口的方法?

 

其实,这就是3.0中新增的扩展函数,扩展函数是一个非常非常有用的东西,它可以通过一个自定义的类扩展其他类的方法。例如:

  1.     class ClassNeedExtensionMethod { }
  2.     static class ClassHasExtensionMethod
  3.     {
  4.         public static void ExtensionMethod(this ClassNeedExtensionMethod cn)
  5.         {
  6.             Console.WriteLine("Extension Method Invoked!");
  7.         }
  8.     }
  9.     class ExtensionMethodTester
  10.     {
  11.         public void Test()
  12.         {
  13.             ClassNeedExtensionMethod cn = new ClassNeedExtensionMethod();
  14.             // 调用扩展方法 方式一
  15.             cn.ExtensionMethod();
  16.             // 调用扩展方法 方式二
  17.             ClassHasExtensionMethod.ExtensionMethod(cn);
  18.         }
  19.     }

 

ClassNeedExtensionMethod是一个空空如也的类,但是在ExtensionMethodTester中却可以调用ExtensionMethod方法!这个方法是在ClassHasExtensionMethod中定义的!

情况是不是和IEnumerable<T>很像?如果把ClassHasExtensionMethod换成Enumerable,把ClassNeedExtensionMethod换成IEnumerable<T>,是不是就和MSDN所描述的情况完全一致了?如果你高兴,甚至可以扩展Object类的方法,太强大了!

不过扩展函数必须是在一个静态类中,并且自身也必须是一个静态函数,调用方法有两种,在上面的代码中已经用红字标出了。

 

扩展函数的出现能解决什么情况?不需要通过类继承的方式来继承某些函数了!

首先我们都知道,一个类只能继承自一个类,但是可以扩展无数个(理论上,不过谁有真的会给一个类继承无数接口呢……)接口。如果你发现类A,类B已经继承自类P,但是又要给A B都再继承一个父类C(这种情况是非常常见的,在项目中再普遍不过了),2.0唯一的做法就是:追根溯源,让P继承自C。万一P又已经继承自M,怎么办?最恶劣的情况,P继承自Page!难道你要让Page类继承自你的C类吗?你和微软商量去,这便导致了父类继承的最经典的情况。

但是有了扩展函数,如果只是要继承方法,而不需要继承变量的话,我们只需要扩展一个接口IC,然后帮IC扩展函数,那A B就具有这个已经定义好的函数了,完全不再需要考虑父类继承问题。

最经典的应用场景:0/R Mapping框架 ActiveRecord,本来需要继承父类以具有Save等方法,但是这样等于限制了以后的类继承条件,现在我们可以改良,使用IActiveRecord,然后帮IActiveRecord扩展Save方法,同样能造成相同的使用而不会影响下层代码的改动,而且不再继承自任何父类!

 

扩展函数,.NET 3.0第三个以人为本的典例。

事实上……小凡觉得微软可能也发现使用LINQ后集合类需要扩展很多方法,但是也出现了类继承问题,于是绞尽脑汁想出了这个扩展函数的解决方案。不管怎么说,这个解决方案很巧妙,的确从根本出发解决了很多问题。

转载于:https://www.cnblogs.com/vanpan/archive/2009/01/07/3583052.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从C# 3.0说以人为本(三)—— 扩展方法 的相关文章

  • Swift语言精要 - Operator(运算符重载)

    运算符重载 Swift的这一语言特性或许应该启发于C 43 43 class Vector2D var x Float 61 0 0 var y Float 61 0 0 init x Float y Float self x 61 x s
  • 关于研究性和工程性

    自己将要往哪个方向发展呢 xff1f 最近一段时间很认真的考虑了一下周围的人 xff0c 有做工程的 xff0c 有做研究的 xff0c 还有做商务的 做工程实际具体 xff0c 相对简单些 xff0c 但是可能薪水也相对低一些 xff1b
  • C#日写点滴(2)

    CTS Common Type System 公共类型系统 C 认可的基本预定义类型并没有内置于C 语言中 xff0c 而是内置于 NET Framework中 例如 xff0c 在C 中声明一个int类型的数据时 xff0c 声明实际上是
  • SQL-关联查询【转】

    T A A表 T B B标 xff0c id为表与表相关联的字段 96 创建相关表结构 span class hljs keyword CREATE span class hljs keyword TABLE Table B span cl
  • char, varchar, nchar, nvarchar (Transact-SQL)

    char 和 varchar Transact SQL 长度固定或可变的字符串数据类型 char n 固定长度 xff0c 非 Unicode 字符串数据 n 用于定义字符串长度 xff0c 并且它必须为 1 到 8 000 之间的值 存储
  • .net中类(class)与结构(struct)的不同

    Class可以被实例化 属于引用类 型 是分配在内存的堆上的 类是引用传递的 Struct属于值类型 是分配在内存的栈上的 结构体是复制传递的 Int32 Boolean等都属于结构体 转载于 https www cnblogs com b
  • Intro to asp.net MVC 简单的小程序(2)

    我们做的很简单 xff0c 就是一个电影的表单 xff0c 显示还有创建 强大的封装真的很好用 xff0c 当我们新建的视图的时候 xff0c 强类型下面都有封装好的 Create List Details 很多 xff0c 我们只要选择一
  • 利用网站上传漏洞使用一句话木马控制服务器

    一句话木马 常用于php asp aspx php lt php echo shell exec GET 39 cmd 39 gt asp lt execute request 34 value 34 gt aspx lt 64 Page
  • 用MotoMidMan给L7批量安装java程序

    在给手机装完驱动后 可以通过MotoMidMan给手机内存安装java程序 需要资源 数据线 MotoMidMan java程序 由一个 jar文件与一个 jad文件组成 操作步骤 1 下载完的是个压缩包 扩展名为 rar 解压完的文件清单
  • 28. Implement strStr()

    public class Solution public int strStr String haystack String needle int next 61 new int needle length generateNextArra
  • Oracle数据库删除了数据如何恢复

    再操作数据库时 xff0c 有时候误删了数据或者更新数据时忘记设置更新条件 xff0c 要是这时候没有提交事务 xff0c 还可以执行回滚操作 要是这时候不小心提交了 xff0c 数据也是可以恢复的 我们只需要执行下面这句sql selec
  • (译)ASP.NET MVC Routing 概述

    ASP NET MVC Routing 概述 在本篇教程中 xff0c 你将会了解到 ASP NET MVC 中一个重要的组件 这个组件叫做 ASP NET Routing xff0c 它负责将客户端请求的路径映射到特定的一个类 Contr
  • eclipse中mysql java驱动的安装

    1 下载mysql connector java x x x zip 2 将压缩包中的mysql connector java x x x bin解压到eclipse中需要导入驱动的工程的根目录下 3 在eclipse中右键该工程选择属性
  • 如何使用gettext, po, mo制作多语言应用程序 (转)

    一 翻译档制作部分 1 制作 po 档 1 生成template文件 xgettext k o ui pref pot ui c pref pot head fuzzy msgid 34 34 msgstr 34 34 34 Project
  • (一) 进程调度

    进程调度算法有FIFO xff0c 优先数调度算法 xff0c 时间片轮转调度算法 xff0c 分级调度算法 xff0c 目前主要是考虑FIFO和优先数调度算法 xff08 静态优先级 xff09 输入 xff1a 进程流文件 xff0c
  • js跳转页面方法(转)

    lt span id 61 34 tiao 34 gt 3 lt span gt lt a href 61 34 javascript countDown 34 gt lt a gt 布丁足迹 秒后自动跳转 lt meta http equ
  • 缓存 ASP.NET 页的某些部分

    生成高性能 可缩放的 Web 应用程序最重要的因素之一是能够在首次请求项时将这些项存储在内存中 xff0c 不管它们是数据对象 页还是页的某些部分 可以将这些项缓存或存储在 Web 服务器上或请求流中的其他软件上 xff0c 如代理服务器或
  • TCP

    RFC 1323 TCP Extensions for High Performance RFC 2488 Enhancing TCP Over Satellite Channels using 传输层端口号定义 https www ian

随机推荐

  • zabbix-proxy安装

    注意 xff0c zabbix proxy的安装和zabbix server的安装不一样 不要混为一谈 xff0c 尤其是数据库的sql结构 rpm ivh http repo zabbix com zabbix 3 0 rhel 6 x8
  • konsole快捷键

    Tab xff1a 自动补全 Ctrl b xff1a 向前移动 xff0c 相当于 lt Left gt Ctrl f xff1a 向后移动 xff0c 相当于 lt Right gt Alt b xff1a 按词向前移动 Alt f x
  • docker中安装了RabbitMQ后无法访问其Web管理页面

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 在官网找了 34 docker run d hostname my rabbit name some rabbit p 8080 15672 rabbitmq 3 mana
  • 网络数据包捕获函数库Libpcap安装与使用(非常强大)

    1 Libpcap简介 Libpcap是Packet Capture Libray的英文缩写 xff0c 即数据包捕获函数库 该库提供的C函数接口用于捕捉经过指定网络接口的数据包 xff0c 该接口应该是被设为混杂模式 这个在原始套接子中有
  • STM32F103控制两个步进电机按照一定转速比运动

    这个暑假没有回家 xff0c 在学校准备九月份的电子设计竞赛 今天想给大家分享一下STM32定时器控制两个步进电机按照一定速度比转动的问题 这次做的05年的电子设计竞赛题目 xff0c 运动悬挂系统 本实验是控制两个步进电机通过一个定滑轮用
  • Android 编程下的 Secret Code

    我们很多人应该都做过这样的操作 xff0c 打开拨号键盘输入 4636 等字符就会弹出一个界面显示手机相关的一些信息 xff0c 这个功能在 Android 中被称为 Android Secret Code xff0c 除了这些系统预置的
  • 用vim格式化代码

    格式化全文 xff1a gg 61 G 自动缩进当前行 xff1a 61 61 这个是原文节选 xff1a 14 6 How do I format indent an entire file You can format indent a
  • C# 之 反射性能优化3

    阅读目录 开始用Delegate优化反射的缺点用Delegate优化反射的优点用CodeDOM优化反射的优点如何用好CodeDOM xff1f 用CodeDOM优化反射的缺点能不能不使用委托 xff1f 根据反射密集程度选择优化方法Code
  • 基于用户行为的视频聚类方案

    在个性化推荐系统中 xff0c 通常是由挖掘物品属性来理解用户兴趣 xff0c 从而构建推荐模型 从用户行为去理解物品属性往往做得比较简单 xff0c 通常只是一些简单的标签统计 为了深入到用户行为去理解内容 xff0c 美拍利用用户的点击
  • .html文件调用接口示例

    直接在 html文件中请求接口的写法示例 span class hljs meta lt DOCTYPE html gt span span class hljs tag lt span class hljs name html span
  • mac os 环境下配置VMware Fusion虚拟机的互通网络

    安装环境 本文基于macOS Sierra 10 12 6系统为例 虚拟机应用VMware Fusion 10 1 3 系统Linux redhat 镜像rhel server 7 4 x86 64 dvd iso VMware Fusio
  • webpack的proxyTable无效的解决方案

    最近遇到这个需要单页访问跨域后台的问题 遇到了网上很多人说的 xff0c proxyTable无论如何修改 xff0c 都没效果的现象 经过几轮测试 xff0c 总结出一下几种解决方案 xff1a 1 xff08 非常重要 xff09 确保
  • 单个LottieAnimationView加载不同的lottie动画

    需求 最近做了一个单个LottieAnimationView根据用户点击选项的不同 xff0c 加载不同的lottie动画的需求 网上的一些demo和博客大多只是单独的加载一个lottie动画 xff0c 普遍不会有问题 xff0c 但是如
  • 使用element-ui中的table中的合计行的show-summary方法总结

    表尾结束景行统计的的问题 使用show summary 和 summary method 61 34 getSummaries 34 这两个方法搭配使用 逻辑处理 在最后必须使用return 出去就行 其中的逻辑可以自行定制 实现后达到的效
  • 如何下载网页所有资源(附源码)

    nodejs扒取html页面中所有链接资源 前言 xff1a 总有些人 xff0c 想下载一个插件 xff0c 能直接获取浏览器显示页面的所有资源 也就是下载一个其他人的网站 xff0c 但是不想一个个复制链接的内容 xff0c 原因大致有
  • Python 实现简单的登录注册界面

    Python 实现简单的登录注册界面 注意 xff1a 编写代码之前需要导入很重要的包 import tkinter as tk import pickle from tkinter import messagebox 主要实现的功能 首先
  • VC窗口抖动源码

    窗口抖动实例 CPoint CurrentPos 抖完还要回到这个位置 xff0c 不要乱跑 CRect rect 这一段计算主要是为了满足SetWindowPos 的参数要求 不解释吧 GetClientRect amp rect Cli
  • Ubuntu编译驱动程序的准备(转)

    ubuntu不带linux内核源码 xff0c 需要自己下载安装 1 xff0c 查看自己的内核版本 uname r 2 xff0c 查看源内的内核源码类表 apt cache search linux source 3 xff0c 下载安
  • 树莓派练习程序(雨水检测)

    水滴检测模块如下 xff1a 树莓派的引脚如下图 xff1a 我们将Vcc引脚连接物理接口2 xff0c GND引脚连接物理接口39 xff0c DO引脚连接物理接口40 实物连接如下图 xff1a 编程使用WiringPi库 xff0c
  • 从C# 3.0说以人为本(三)—— 扩展方法

    说完了LINQ的语言支持和语法灵活 xff0c 下面就是一个非常有用的东东 扩展方法 xff08 Extension Method 还记得我们看了好几遍的LINQ吧 xff0c 下面这个 xff1a var numQuery 61 from