文档章节

c# params 工作原理。

魂祭心
 魂祭心
发布于 2015/10/14 12:28
字数 632
阅读 136
收藏 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[]),会提示已存在.在这里也能解释为什么在既可变参,也可定参的情况下使用定参的原因了.使用变参需要额外的代码打包参数.























© 著作权归作者所有

共有 人打赏支持
魂祭心
粉丝 12
博文 50
码字总数 81549
作品 0
浦东
后端工程师
[开源世界]从自动导出动态链接库接口看C++的缺点

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

梁欢
2013/10/21
0
2
深入浅出OOP(一): 多态和继承(早期绑定/编译时多态)

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

葡萄城控件技术团队
2015/04/02
0
0
请问一下,我用c# 写一个服务器,怎么根据用户请求的URL来转向到相应的页面?

我才刚开始学习C#,请问一下,我用c# 写一个服务器,怎么根据用户请求的URL来转向到相应的页面? 比如:用户请求:http://127.0.0.1:8090/Test/Login?username=1&password=2,此时要读取服务器目...

小_M
2017/03/31
130
0
AsyncTask 的实现原理

在《Android异步处理二:使用AsyncTask异步更新UI界面》一文中,我们介绍了如何使用AsyncTask实现异步下载图片,并且更新图片到UI界面的方法。本篇我们将学习Framework层AsyncTask的实现原理...

鉴客
2011/09/17
7.5K
1
c#实现动态加载Dll

原文:c#实现动态加载Dll 原理如下: 1、利用反射进行动态加载和调用. Assembly assembly=Assembly.LoadFrom(DllPath); //利用dll的路径加载,同时将此程序集所依赖的程序集加载进来,需后辍名....

杰克.陈
2017/12/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

中国移动蔡谦:5G传输准备就绪

目前5G已成业界热议话题,在即将到来的万物互联时代,5G是非常关键的技术。且5G相比4G,业务场景多种多样,对5G承载网带来巨大挑战。5G传输,承载先行并不仅仅是一个口号。当前5G承载网的部署...

linux-tao
21分钟前
4
0
维护“修理权”,苹果使用专有软件工具来修复MacBook Pro和iMac Pro

根据上月发给苹果授权服务提供商的一份文件,苹果公司正在使用新的专有软件诊断工具来修复MacBook Pros和iMac Pros,如果不用专有软件工具来修复关键部件,将会导致“系统失效和修复不完整”...

linuxCool
51分钟前
2
0
cacti监控安装

cacti是用PHP实现的一个软件,它用snmp服务获取数据,然后用rrdtool存储和更新数据,并生成图表展示。比较适合用于交换机、路由器的网络监控,插件众多,可图示化显示网络状况。 cacti官方推...

hiwill
今天
4
0
shell特殊符号、cut、sort、uniq、wc、tee、tr、split命令

10月15日任务 8.10 shell特殊符号cut命令 8.11 sort_wc_uniq命令 8.12 tee_tr_split命令 8.13 shell特殊符号下 cut 命令 cut作用:截取字符串 用法如下:cat /etc/passwd |head -2 |cut -d ...

hhpuppy
今天
4
0
Springboot实现filter拦截token验证和跨域

背景 web验证授权合法的一般分为下面几种 1使用session作为验证合法用户访问的验证方式 使用自己实现的token 使用OCA标准 在使用API接口授权验证时,token是自定义的方式实现起来不需要引入其...

funnymin
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部