文档章节

c# params 工作原理。

魂祭心
 魂祭心
发布于 2015/10/14 12:28
字数 632
阅读 149
收藏 1

#程序员薪资揭榜#你做程序员几年了?月薪多少?发量还在么?>>>

高级语言之所以成为高级语言,编译器付出了很多。params在给我们带来方便的同时,编译器也是贡献不少。

实例代码:

using System;
public class Test
{	
        public static void Main()
	{    
             Console.WriteLine("结果1");	
             say("hello","world");
             Console.WriteLine("结果2");	
             say("aaaa","sssss","ddddd");
            Console.ReadKey();
        }
	public static void say(string str,string str2)	
        {	
             Console.WriteLine("single");
	     Console.WriteLine(str);
             Console.WriteLine(str2);	
        }
	public static void say(params string[] str)
	{
	    Console.WriteLine("params");
	    foreach(string s in str)	    
            {
	        Console.WriteLine(s);
            }
        }
}

说明下目的,

 say("hello","world");

是为了验证在参数同时适配

public static void say(string str,string str2)

public static void say(params string[] str)

的时候,编译器是调用哪个函数。

  say("aaaa","sssss","ddddd");

是为了察看params的运作过程

代码结果:

分析:

从结果1可看出在同时符合确定变量和可变变量的时候,编译器调用的是确定变量的函数,至于原因等说完params在提。

反编译这段代码。

注意参数,这里并没有出现params字样,说明到这个层级是不存在params了,接着看main函数。

.method public hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       79 (0x4f)
  .maxstack  3
  .locals init (string[] V_0)
  IL_0000:  ldstr      bytearray (D3 7E 9C 67 31 00 )                               // .~.g1.
  IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000a:  ldstr      "hello"
  IL_000f:  ldstr      "world"
  IL_0014:  call       void Test::say(string,
                                      string)                                                       // 结果1的调用
  IL_0019:  ldstr      bytearray (D3 7E 9C 67 32 00 )                               // .~.g2.
  IL_001e:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0023:  ldc.i4.3
  IL_0024:  newarr     [mscorlib]System.String
  IL_0029:  stloc.0
  IL_002a:  ldloc.0
  IL_002b:  ldc.i4.0
  IL_002c:  ldstr      "aaaa"
  IL_0031:  stelem.ref
  IL_0032:  ldloc.0
  IL_0033:  ldc.i4.1
  IL_0034:  ldstr      "sssss"
  IL_0039:  stelem.ref
  IL_003a:  ldloc.0
  IL_003b:  ldc.i4.2
  IL_003c:  ldstr      "ddddd"
  IL_0041:  stelem.ref
  IL_0042:  ldloc.0
  IL_0043:  call       void Test::say(string[])                                       //结果2的调用
  IL_0048:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
  IL_004d:  pop
  IL_004e:  ret
} // end of method Test::Main

从结果1可以清楚地看到调用的是确定参数函数,往下的IL_0024构建了一个数组,然后在一个个的把参数推送进数组,最后调用了say(string[] )函数.

结论: 

params的实现只是将单个的参数打包成数组,,调用数组参数函数,事实上你并不能同时声明,say(string[])和say(params string[]),会提示已存在.在这里也能解释为什么在既可变参,也可定参的情况下使用定参的原因了.使用变参需要额外的代码打包参数.























© 著作权归作者所有

魂祭心

魂祭心

粉丝 14
博文 53
码字总数 88077
作品 0
浦东
后端工程师
私信 提问
加载中

评论(0)

[开源世界]从自动导出动态链接库接口看C++的缺点

自动导出动态链接库接口在C++编程中绝对是一件烦人的事情,因为你不得不大量的重复以下几个步骤: 1.加载动态链接库 2.定义导出函数指针定义 3.定义导出函数指针变量 4.从动态链接库中导出函...

梁欢
2013/10/21
550
2
c#中可变参数params关键字学习

引用 https://www.cnblogs.com/maowp/p/8134342.html 基础知识 1、概念 params 是C#开发语言中关键字, params主要的用处是在给函数传参数的时候用,就是当函数的参数不固定的时候。 在方法声...

osc_218tfwfw
2018/12/13
3
0
深入浅出OOP(一): 多态和继承(早期绑定/编译时多态)

在本系列中,我们以CodeProject上比较火的OOP系列博客为主,进行OOP深入浅出展现。 无论作为软件设计的高手、或者菜鸟,对于架构设计而言,均需要多次重构、取舍,以有利于整个软件项目的健康...

葡萄城控件技术团队
2015/04/02
266
0
通过源码看原理之 selenium

selenium的历史 1. selenium1.x:这个时候的selenium,使用的是JavaScript注入技术与浏览器打交道,需要Selenium RC启动一个Server,将操作Web元素的API调用转化为一段段Javascript,在Selen...

osc_6ogjsu3t
2019/03/04
3
0
android之AsyncTask

AsyncTask和Handler对比 1 ) AsyncTask实现的原理,和适用的优缺点 AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(...

长平狐
2013/12/25
60
0

没有更多内容

加载失败,请刷新页面

加载更多

Python--报错RecursionError: maximum recursion depth exceeded in comparison

Python--报错RecursionError: maximum recursion depth exceeded in comparison 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本...

归子莫
昨天
21
0
聊聊SpinalTap的BinlogEventListener

序 本文主要研究一下SpinalTap的BinlogEventListener BinlogEventListener SpinalTap/spinaltap-mysql/src/main/java/com/airbnb/spinaltap/mysql/binlog_connector/BinaryLogConnectorSourc......

go4it
昨天
29
0
Spring的扩展原理

MainConfigOfExt.class /** * 扩展原理: * 1. BeanPostProcessor:bean后置处理器;bean创建对象初始化前后进行拦截工作 * BeanFactoryPostProcessor:beanFactory的后置处理器 * ...

与你同行7
昨天
37
0
C# 基础知识系列- 16 开发工具篇

0. 前言 这是C# 基础知识系列的最后一个内容讲解篇,下一篇是基础知识-实战篇。这一篇主要讲解一下C#程序的结构和主要编程工具。 1. 工具 工欲善其事必先利其器,在实际动手之前我们先来看看...

月影南溪
昨天
15
0
阿里双11超级工程:PB级文件分发重器蜻蜓

有图有介绍见: http://tech.it168.com/a2017/1114/3179/000003179630.shtml 蜻蜓开源地址:https://github.com/alibaba/dragonfly 2017天猫双11, 交易峰值32.5万/秒,支付峰值25.6万/秒,数...

whoisliang
昨天
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部