首页 > 编程语言 >c# 扩展方法

c# 扩展方法

时间:2023-04-17 18:23:29浏览次数:34  
标签:调用 c# 扩展 实例 类型 方法

由来

一个类想要有新的方法,除了简单粗暴的在类中直接添加,当然可以用继承来实现,不过若为扩展一个方法就用继承,这就大材小用了,况且有些类是不能被继承的。于是乎,c#3.0提出了扩展方法,用它来为现有的类型(比如自定义的类)添加方法。

如何定义扩展方法

a) 扩展方法必须在非嵌套(类中类)非泛型的静态类中定义

b) 他至少要有一个参数;

c) 第一个参数必须加this关键字作为前缀(第一个参数类型也称为扩展类型,即指方法对这个类型进行扩展);

d) 第一个参数不能使用任何其他的修饰符(如不能用ref、out等修饰符)

e) 第一个参数的类型不能是指针类型。

注意

c#的代码智能提示中,扩展方法前面都有一个向下的箭头标识。

当我们为一个类型定义扩展方法时,应尽量扩展具体的类型,而不要扩展其基类。

扩展方法无法访问它们所扩展的类型中的私有变量。

编译器如何发现扩展方法

当他看到某个类型的变量在调用方法时,它首先去对象的实例方法中进行查找,如果没有找到与调用方法同名并且参数一致的实例方法,编译器就会去查找是否存在合适的扩展方法。

若从编译器发现扩展方法的过程来看,方法调用的优先级顺序应为:

类型的实例方法——当前命名空间下的扩展方法——导入命名空间的扩展方法。

空引用也可以调用扩展方法。

在c#中,在空引用(即null)上调用实例方法是会引发NullReferenceException异常的,但在空引用上却可以调用扩展方法。这是因为对编译器而言,这个过程就是把空引用对象(或者说变量)当成参数传入静态方法(扩展方法)而已;所以这并不是真正的在空引用上调用方法,故不会出错。//以上是可以通过IL代码来证实的。

怎么调用扩展方法

  • 像调用被扩展类型的实例对象的其它实例方法一样调用。
  • 静态方法调用方式。类名用定义扩展方法时所在的类。

代码示例

/*main 方法*/
Console.WriteLine(DateTime.Now.GetDatetimeStr());
Console.WriteLine(ExtendClass.GetDatetimeStr(DateTime.Now));

//扩展类
public static class ExtendClass
{
    public static string GetDatetimeStr(this DateTime dateTime)
    {
        return dateTime.ToString("yyyy年MM月dd日 HH时mm分ss秒"); 
    }
}

输出:

2023年04月17日 18时06分22秒
2023年04月17日 18时06分22秒


更新于:2023-04-17

标签:调用,c#,扩展,实例,类型,方法
From: https://www.cnblogs.com/idasheng/p/17326714.html

相关文章

  • opencv c++ 保存为位深度为1的png
    vector<int>compression_params;compression_params.push_back(IMWRITE_PNG_COMPRESSION);compression_params.push_back(3);compression_params.push_back(IMWRITE_PNG_BILEVEL);compression_params.push_back(1);imwrite("text2.png&......
  • 文本编辑器 实现ctrl+v粘贴图片并上传、word粘贴带图片
    ​ 当前功能基于PHP,其它语言流程大抵相同。大概流程:1.将docx文件上传到服务器中2.使用PHPoffice/PHPword实现将word转换为HTML3.将HTML代码返回并赋值到编辑器中 1编辑器配置修改1.1新增上传wordjson配置在ueditor\php\config.json中新增如下配置:     /*......
  • 编程打卡:C语言趣味编程习题做
    编程打卡:C语言趣味编程习题做数制转换问题描述给定一个M进制的数x,实现对x向任意非M进制的数的转换。设计思路输入M进制的数x,将x转换为十进制数,再将十进制数转换为任意非M进制的数。流程图graphA["开始"]-->B["输入M进制的数x"]-->C["将x转换为十进制数"]-->D["将十进......
  • 2-211-(LeetCode-470) 用 Rand7() 实现 Rand10()
     1.题目 https://leetcode.cn/problems/implement-rand10-using-rand7/submissions/425373186/ 2.解法 classSolutionextendsSolBase{publicintrand10(){inttemp=40;while(temp>=40){temp=(rand7()-1)*7......
  • CF1646E Power Board 题解
    题目链接:https://codeforces.com/contest/1646/problem/E题目大意:有一个\(n\timesm\)的矩阵,其中第\(i\)行第\(j\)列的格子中的数字是\(i^j\)。问:矩阵中存在多少个不同的数?解题思路:可以很明显地发现,第\(1\)行的数字全部都是\(1\),而且在其它行不会出现数值为\(1\)......
  • Docker基础命令及面试问题
    Docker包括三个基本概念:镜像(Image):Docker镜像(Image),就相当于是一个root文件系统。比如官方镜像ubuntu:16.04就包含了完整的一套Ubuntu16.04最小系统的root文件系统。容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定......
  • Failed to process import candidates for configuration class [springfox.documenta
     org.springframework.beans.factory.BeanDefinitionStoreException:Failedtoprocessimportcandidatesforconfigurationclass[springfox.documentation.swagger2.configuration.Swagger2DocumentationConfiguration];nestedexceptionisjava.lang.IllegalArgumen......
  • 连接MongoDB+Docker安装MongoDB
    一、连接MongoDB工具:studio3T下载:https://studio3t.com/download-thank-you/?OS=win641、无设置密码最终成功页面2、设置了密码后续同1二、安装MongoDB版本:5.0.5参考:https://www.cnblogs.com/cwp-bg/p/10403327.htmlhttps://blog.csdn.net/weixin_4......
  • 【Spring MVC + Tomcat】Spring MVC 传统VS现代方式的启动过程对比
    1 前言这节我们来讨论下SpringMVC传统和现在的启动方式的不同,可能大家现在上手就是SpringBoot直接给我们内置Tomcat,我们最多也就是改改配置就完事了,我记得我上学的时候写SSM的时候,还要整理各种Jar包和配置,这节我们就来对比下两种启动方式是如何启动SpringMVC的哈。2  传......
  • access violation at address isflash.dll
    右击“我的电脑”。单击“属性”。 在“系统属性”中单击“高级”。 在“性能”中单击“设置”。 在“性能选项”中单击“数据执行保护”。 单击“添加”。选择要运行的程序。 OK。就这么简单。 ......