文档章节

c# params 工作原理。

魂祭心
 魂祭心
发布于 2015/10/14 12:28
字数 632
阅读 134
收藏 1
点赞 0
评论 0

高级语言之所以成为高级语言,编译器付出了很多。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[]),会提示已存在.在这里也能解释为什么在既可变参,也可定参的情况下使用定参的原因了.使用变参需要额外的代码打包参数.























© 著作权归作者所有

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

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

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

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

葡萄城控件技术团队
2015/04/02
0
0
AsyncTask 的实现原理

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

鉴客
2011/09/17
7.5K
1
请问一下,我用c# 写一个服务器,怎么根据用户请求的URL来转向到相应的页面?

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

小_M
2017/03/31
130
0
c#实现动态加载Dll

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

杰克.陈
2017/12/03
0
0
android之AsyncTask

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

长平狐
2013/12/25
32
0
android AsyncTask介绍

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

墨梅
2014/10/29
0
0
《CLR Via C# 第3版》笔记之(十) - 可选参数和可变数量参数

C#中也可以像动态语言那样,定义可选参数和可变数量参数。通过使用可选参数和可变数量参数可以构建更加灵活的函数。 主要内容: 可选参数 可变数量参数 1. 可选参数 可选参数即调用函数时,传...

zting科技
2017/11/09
0
0
MediaWiki自动登陆和更新页面

Mediawiki系统开放了API,向wiki系统的api.php发送http请求,可实现很多功能。 1.登陆:原理可查看mediawiki api文档 # Login userName = '***' password = '***' headers = dict() headers...

TinkerS
2012/04/09
0
0
C# 关键字ref 和out 的详细区别

ref 和 out 的详细区别 ref和out都是C#中的关键字,所实现的功能也差不多,都是指定一个参数按照引用传递。 对于编译后的程序而言,它们之间没有任何区别,也就是说它们只有语法区别。 总结起...

老朱教授
2017/11/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式 Factory工厂模式 Singleton单例模式 Delegate委派模式 Strategy策略模式 Prototype原型模式 Template模板模式 Spring5 beans 接口实例化 代理Bean操作 ...

小致dad
17分钟前
0
0
SpringBoot | 第十章:Swagger2的集成和使用

前言 前一章节介绍了mybatisPlus的集成和简单使用,本章节开始接着上一章节的用户表,进行Swagger2的集成。现在都奉行前后端分离开发和微服务大行其道,分微服务及前后端分离后,前后端开发的...

oKong
今天
9
0
Python 最小二乘法 拟合 二次曲线

Python 二次拟合 随机生成数据,并且加上噪声干扰 构造需要拟合的函数形式,使用最小二乘法进行拟合 输出拟合后的参数 将拟合后的函数与原始数据绘图后进行对比 import numpy as npimport...

阿豪boy
今天
12
0
云拿 无人便利店

附近(上海市-航南路)开了家无人便利店.特意进去体验了一下.下面把自己看到的跟大家分享下. 经得现场工作人员同意后拍了几张照片.从外面看是这样.店门口的指导里强调:不要一次扫码多个人进入....

周翔
昨天
1
0
Java设计模式学习之工厂模式

在Java(或者叫做面向对象语言)的世界中,工厂模式被广泛应用于项目中,也许你并没有听说过,不过也许你已经在使用了。 简单来说,工厂模式的出现源于增加程序序的可扩展性,降低耦合度。之...

路小磊
昨天
203
1
npm profile 新功能介绍

转载地址 npm profile 新功能介绍 npm新版本新推来一个功能,npm profile,这个可以更改自己简介信息的命令,以后可以不用去登录网站来修改自己的简介了 具体的这个功能的支持大概是在6这个版...

durban
昨天
1
0
Serial2Ethernet Bi-redirection

Serial Tool Serial Tool is a utility for developing serial communications, custom protocols or device testing. You can set up bytes to send accordingly to your protocol and save......

zungyiu
昨天
1
0
python里求解物理学上的双弹簧质能系统

物理的模型如下: 在这个系统里有两个物体,它们的质量分别是m1和m2,被两个弹簧连接在一起,伸缩系统为k1和k2,左端固定。假定没有外力时,两个弹簧的长度为L1和L2。 由于两物体有重力,那么...

wangxuwei
昨天
0
0
apolloxlua 介绍

##项目介绍 apolloxlua 目前支持javascript到lua的翻译。可以在openresty和luajit里使用。这个工具分为两种模式, 一种是web模式,可以通过网页使用。另外一种是tool模式, 通常作为大规模翻...

钟元OSS
昨天
2
0
Mybatis入门

简介: 定义:Mybatis是一个支持普通SQL查询、存储过程和高级映射的持久层框架。 途径:MyBatis通过XML文件或者注解的形式配置映射,实现数据库查询。 特性:动态SQL语句。 文件结构:Mybat...

霍淇滨
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部