[C#3] 1-扩展方法
时间:2022-04-23
本文章向大家介绍[C#3] 1-扩展方法,主要内容包括1.从DEMO开始、2.扩展方法剖析、3.总结、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
1.从DEMO开始
先看一个扩展方法的例子:
1 class Program
2 {
3 public static void Main()
4 {
5 Int32 myNum = 1;
6 myNum = myNum.AddToOldNum(1);
7 Console.WriteLine(myNum);
8 }
9 }
10
11 public static class ExpandInt
12 {
13 //扩展方法必须为静态方法
14 public static int AddToOldNum(this int oldNum,int newNum)
15 {
16 return oldNum + newNum;
17 }
18 }
为一个类型扩展一个方法如此只简单,但是它究竟为我们做了什么呢,为什么我可以调用的AddToOldNum方法?还是让我们从IL代码层面来看看吧。
2.扩展方法剖析
这里是上面代码编译的IL:
1 .method public hidebysig static int32 AddToOldNum(
2 int32 oldNum, int32 newNum) cil managed
3 {
4 .custom instance void [System.Core]
5 System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
6 // 代码大小 9 (0x9)
7 .maxstack 2
8 .locals init ([0] int32 CS$1$0000)
9 IL_0000: nop
10 IL_0001: ldarg.0
11 IL_0002: ldarg.1
12 IL_0003: add
13 IL_0004: stloc.0
14 IL_0005: br.s IL_0007
15 IL_0007: ldloc.0
16 IL_0008: ret
17 } // end of method ExpandInt::AddToOldNum
发现它和一般的静态方法没什么区别,唯一不同的是多了一行调用[System.Runtime.CompilerServices.ExtensionAttribute]:
custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
MSDN告诉我System.Runtime.CompilerServices.ExtensionAttribute表明一个法是一种可拓方法, 或一个类或集合包含扩展方法【这里我也不太懂,嘿嘿】。从这个类型的结尾Extension_Attribute_就可看出它是一个特性类。 为我们的AddToOldNum方法添加了必要的元数据。
再来看看Main方法里发生了什么情况:
1 .method public hidebysig static void Main() cil managed
2 {
3 .entrypoint
4 // 代码大小 19 (0x13)
5 .maxstack 2
6 .locals init ([0] int32 myNum)
7 IL_0000: nop
8 IL_0001: ldc.i4.1
9 IL_0002: stloc.0
10 IL_0003: ldloc.0
11 IL_0004: ldc.i4.1
12 IL_0005: call int32 ConsoleApplication1.ExpandInt::AddToOldNum(
13 int32, int32)
14 IL_000a: stloc.0
15 IL_000b: ldloc.0
16 IL_000c: call void [mscorlib]System.Console::WriteLine(int32)
17 IL_0011: nop
18 IL_0012: ret
19 } // end of method Program::Main
注意这一行,编译器把我们写的myNum = myNum.AddToOldNum(1)编译成这样:
IL_0005: call int32 ConsoleApplication1.ExpandInt::AddToOldNum(int32,int32)
"实例方法"的调用换成了ExpandInt::AddToOldNum(int32,int32)静态方法的调用,这就是扩展方法的本质所在了。
3.总结
我们真的扩展了Int32类的实例方法了吗?没有,编译器帮我们披了一层外衣, 把对“实例方法”的调用在编译时期改变成了静态类中的静态方法的调用,所以扩展方法是一种编译时技术。当扩展方法和实例方法签名相同时,实例方法优先使用。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 数据挖掘从入门到放弃:线性回归和逻辑回归
- 【Flutter 实战】文件系统目录
- 【原创】Spring Boot终极篇《上》
- 【原创】Spring Boot终极篇《下》
- 面试官:JDK、JRE、JVM 三者什么关系?
- 面试官:什么是面向对象?
- 详解SpringCloud中RabbitMQ消息队列原理及配置,一篇就够!
- 面试官:什么是字节码?它最大的优势是什么?
- 数组转List,一定要小心这个坑!
- 【小白学PyTorch】5.torchvision预训练模型与数据集全览
- 实战 | Python爬取B站柯南弹幕+Gephi梳理主线剧情
- Docker 部署SpringBoot项目不香吗?
- 面试官写了个双冒号::问我这是什么语法?Java中有这玩意?
- 精解四大集合框架:List核心知识总结
- 【深度学习】Keras vs PyTorch vs Caffe:CNN实现对比