参数


可选参数与命名参数

  设计方法时,我们可以为部分参数设置默认值,在方法调用时就可以不提供该参数,使用其默认值。此外,调用方法时可以通过指定参数名的方式来传递参数。话不多说,请看以下示例:

  1. static void Main(string[] args)
  2. {
  3. SomeMethod(); //X=0,Y=0,Z=0
  4. SomeMethod(y: 5, z: 10); //X=0,Y=5,Z=10
  5. Console.ReadLine();
  6. }
  7. private static void SomeMethod(int x = 0, int y = 0, int z = 0)
  8. {
  9. Console.WriteLine($"X={x},Y={y},Z={z}");
  10. }

上述SomeMethod方法,接受Int类型参数x、y、z,并设置默认值0。第1次调用时没有指定参数,C#编译器自动嵌入参数的默认值。第2次则为y和z参数显示指定了要传递的值。

可选参数的使用规则

  • 有默认值的参数必须放在没有参数值的所有参数之后。
  • 默认值必须是编译时能确定的常量值(例如不能将参数的默认值设置为DateTime.Now)。
  • 不能重命名参数变量。
  • 更改参数的默认值具有潜在的危险性(调用该方法可能产生意料之外的结果)。
  • 如果参数使用ref或out关键字标识,就不能设置默认值。

以传递引用的方式传递参数

  在方法中,参数是值类型还是引用类型,两种情况下的处理方式有着明显的不同。

  1. static void Main(string[] args)
  2. {
  3. int i = 0;
  4. GetVal(i);
  5. Console.WriteLine(i); //0
  6. int[] arr = new int[] { 0 };
  7. GetVal(arr);
  8. Console.WriteLine(arr[0].ToString()); //10
  9. Console.ReadLine();
  10. }
  11. private static void GetVal(int p_Int)
  12. {
  13. p_Int = 10;
  14. }
  15. private static void GetVal(int[] p_Arr)
  16. {
  17. p_Arr[0] = 10;
  18. }

对于值类型实例,传递给方法的是实例的一个副本,方法中对这个副本的操作不影响调用者中的实例;对于引用类型实例,传递给方法的是实例对象的引用(或者说指向对象的指针)。CLR允许以传引用而非传值的方式传递参数,在C#中,使用out或ref关键字实现此功能。

out和ref关键字的区别

使用ref关键字时,调用方法前必须初始化参数的值,被调用的方法可以对该值进行读取或写入;使用out关键字时,在调用方法之前可以不进行初始化,必须在方法中进行初始化

如下,向GetVal传递未经初始化的参数str2时,无法通过编译。

  1. static void Main(string[] args)
  2. {
  3. string str = "before Porcess";
  4. GetVal(ref str);
  5. Console.WriteLine(str);
  6. string str2;
  7. GetVal(ref str2); //Error:Use of unassigned local variable 'str2'
  8. Console.WriteLine(str2);
  9. Console.ReadLine();
  10. }
  11. private static void GetVal(ref string p_Str)
  12. {
  13. p_Str = "Processed";
  14. }

修改上述GetVal方法,在方法内部不对参数进行初始化,依旧无法通过编译。

  1. //Error:The out parameter 'p_Str' must be assigned to before control leaves the current method
  2. private static void GetVal(out string p_Str)
  3. {
  4. string anotherStr = "Processed";
  5. }

值类型使用out和ref

  1. static void Main(string[] args)
  2. {
  3. int i = 0;
  4. GetVal(ref i);
  5. Console.WriteLine(i); //10
  6. Console.ReadLine();
  7. }
  8. private static void GetVal(ref int p_Int)
  9. {
  10. p_Int = 10;
  11. }

上述代码,使用ref关键字,将变量i的地址传递给GetVal,p_Int是一个指针,指向Main栈帧中的i的值。在GetVal方法内部,p_Int指向的值被修改为10。

引用类型使用out和ref

  1. static void Main(string[] args)
  2. {
  3. int[] arr = new int[] { 0 };
  4. GetVal(arr);
  5. //GetVal(ref arr);
  6. Console.WriteLine(arr[0].ToString()); //0
  7. Console.ReadLine();
  8. }
  9. private static void GetVal(int[] p_Arr)
  10. //private static void GetVal(ref int[] p_Arr)
  11. {
  12. p_Arr = new int[] { 0 };
  13. p_Arr[0] = 10;
  14. }

这段代码输出的结果是0,和本节开头为方法传递数组的示例输出结果不太相同。差别仅为在方法中构造了一个新的对象,从输出结果可以看出,新对象的指针并没有返回给调用者。为了将新对象返回给调用者,可以使用out和ref关键字(注释掉的部分)。

注意:以传递引用的方式传给方法变量时,参数类型必须与方法签名中声明的类型完全一致。

可变数量参数

  方法有时需要获取可变数量的参数,使用params关键字,使方法能够接受可变数量的参数。

  1. static void Main(string[] args)
  2. {
  3. int i = Add(1, 2, 3, 4, 5, 6, 7, 8, 9);
  4. Console.WriteLine(i);
  5. Console.ReadLine();
  6. }
  7. private static int Add(params int[] p_Arr)
  8. {
  9. int sum = 0;
  10. for (int i = 0; i < p_Arr.Length; i++)
  11. {
  12. sum += p_Arr[i];
  13. }
  14. return sum;
  15. }

使用params关键字时,编译器会向参数应用定制特性System.ParamArrayAttribute的一个实例。

执行步骤:

  1. 当C#编译器检测到方法调用时,会首先检查所有具有指定名称、同时参数没有应用ParamArray特性的方法。
  2. 如果找到匹配的方法,就生成调用的代码。
  3. 如果没有找到,就接着检查应用了ParamArray特性的方法。
  4. 找到匹配的方法,编译器先生成代码构造一个数组,填充元素,再生成代码来调用所选的方法。

C#参数详解的更多相关文章

  1. Nginx主配置参数详解,Nginx配置网站

    1.Niginx主配置文件参数详解 a.上面博客说了在Linux中安装nginx.博文地址为:http://www.cnblogs.com/hanyinglong/p/5102141.html b.当 ...

  2. iptables参数详解

    iptables参数详解 搬运工:尹正杰 注:此片文章来源于linux社区. Iptalbes 是用来设置.维护和检查Linux内核的IP包过滤规则的. 可以定义不同的表,每个表都包含几个内部的链,也 ...

  3. chattr的常用参数详解

    chattr的常用参数详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在实际生产环境中,有的运维工程师不得不和开发和测试打交道,在我们公司最常见的就是部署接口.每天每个人部署的 ...

  4. mha配置参数详解

    mha配置参数详解: 参数名字 是否必须 参数作用域 默认值 示例 hostname Yes Local Only - hostname=mysql_server1, hostname=192.168 ...

  5. $.ajax()方法所有参数详解;$.get(),$.post(),$.getJSON(),$.ajax()详解

    [一]$.ajax()所有参数详解 url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. type: 要求为String类型的参数,请求方式(post或get)默认为get.注 ...

  6. linux PHP 编译安装参数详解

    linux PHP 编译安装参数详解 ./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc -- ...

  7. 【转】jqGrid 各种参数 详解

      [原文]http://www.cnblogs.com/younggun/archive/2012/08/27/2657922.htmljqGrid 各种参数 详解 JQGrid JQGrid是一个 ...

  8. HTML滚动字幕代码参数详解及Js间隔滚动代码

    html文字滚动代码 <marquee style="WIDTH: 388px; HEIGHT: 200px" scrollamount="2" dire ...

  9. mysql5.6主从参数详解

    mysql5.6的主从相当的不错,增加了不少参数,提升了主从同步的安全和效率,以下是mysql5.6主从参数详解. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

  10. Linux 之 编译器 gcc/g++参数详解

    2016年12月9日16:48:53 ----------------------------- 内容目录: [介绍] gcc and g++分别是gnu的c & c++编译器 gcc/g++ ...

随机推荐

  1. JAVA中的四种引用以及ReferenceQueue和WeakHashMap的使用示例

    简介: 本文主要介绍JAVA中的四种引用: StrongReference(强引用).SoftReferenc(软引用).WeakReferenc(弱引用).PhantomReference(虚引用) ...

  2. 编译器报错:'IHTMLControlElement' : redefinition

    由于我安装了platform SDK,编译导致错误: error C2367: 'IHTMLControlElement' : redefinition; different uuid specifi ...

  3. noip提高组1999 导弹拦截

    导弹拦截 背景 实中编程者联盟为了培养技术精湛的后备人才,必须从基础题开始训练. 描述 某国为了防御敌国的导弹袭击,研发出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任 ...

  4. 菜鸟的Xamarin.Forms前行之路——按钮的按下抬起事件的监控(可扩展至其他事件)

    提问:监控按钮的点击事件,可以通过按钮的Click事件,或者Command绑定,那么如何监控按钮的按下与抬起,或者移动,长按,双击等事件? 解决方法:各个平台自定义渲染依赖注入. 共享项目PCL: 1 ...

  5. C语言指针(三)指针传递给函数

    实例1:传递一个无符号的long型指针给该函数 #include<stdio.h>#include<time.h>void getSeconds(unsignedlong*pa ...

  6. MySQL (九)

    1 代码执行结构 代码执行结构有三种:顺序结构.分支结构和循环结构. 1.1 分支结构 分支结构:实现准备多个代码块,按照条件选择性执行某段代码. 在MySQL中只有if分支. 基本语法 if 条件判 ...

  7. 电脑重装系统按什么键进U盘PE

    电脑重装系统按什么键进U盘PE... -------------------------- 各品牌电脑重装系统快捷按键进U盘PE: -------------------------- Dell电脑重 ...

  8. MySQL使用聚合函数查询

    create table `t_grade` ( `id` int , `stuName` varchar (60), `course` varchar (60), `score` int ); in ...

  9. Docker 集群环境实现方式

    Docker 集群环境实现的新方式 近几年来,Docker 作为一个开源的应用容器引擎,深受广大开发者的欢迎.随着 Docker 生态圈的不断建设,应用领域越来越广.云计算,大数据,移动技术的快速发展 ...

  10. .NET技术基础总结 ----第一章

    . 一..NET定义 很多人常说我是做.NET开发的,但是,NET到底是什么呢?是一个开发工具?还是一个平台?或者是一个软件环境? 其实,我觉得吧,他是一种概念.一种构想吧.微软的产品发布会上,主持人 ...