当前位置: 首页 > news >正文

跟小静读CLR via C#(10)-参数

最近几天学了参数,其实对于参数本不陌生,从上学学C语言基础的时候就学过了。不过细心学下来,还是收获了一些。


一、 命名参数、可选参数

命名参数和可选参数是在Visual C#2010中引入的新特性。 笨地儿我个瓜不兮兮的,今天才知道高脚杯

  • 可选参数:定义方法时为参数设置默认值,调用该方法时可以省略为某些形参指定实参。
  • 命名参数:调用方法时,通过指定参数名称的方式为特定形参指定实参。指定时是根据名称将形参和实参关联,而不是与参数在列表中的位置关联。

例如:

class Program
    {
        static void Main(string[] args)
        {
            //可选参数
            Employee.DisplayInfo(24, "程序员");         //相当于 Employee.DisplayInfo(24, "程序员", 0, "未知",default(datetime)); 
            Employee.DisplayInfo(25, "英语相关", 9500); //相当于 Employee.DisplayInfo(25, "英语相关", 9500,"未知",default(datetime));
            //命名参数
            //相当于Employee.DisplayInfo(30, "高级软件工程师", 20000, "Yathur",DateTime.Now);
            Employee.DisplayInfo(30, Job: "高级软件工程师", Salary: 20000, Name: "Yathur", dt: DateTime.Now);
            Employee.DisplayInfo(Age: 25, Job: "教师");
            Console.Read();
        }
    }
    public class Employee
    {
        public static void DisplayInfo(int Age, string Job, int Salary = default(int), string Name = "未知", DateTime dt = default(DateTime))
        {
            Console.WriteLine("姓名:" + Name + ",   年龄:" + Age + ",   职位:" + Job + ",   月薪" + Salary + "   " + dt);
        }
    }运行结果:

image

 

在智能感知中,可选参数为方括号标识。

image

有了命名参数,调用时可以方便地按照形参名称进行,我们不需要记住或查找形参在所调用方法的形参列表中的顺序。 有了可选参数,当面对包含大量参数的方法时,如果含有默认值,我们可以只给有意义的参数指定实参,用起来方便了很多。

使用规则:
  • 未设置默认值的参数也可以按名称传递。

Employee.DisplayInfo( Age:25,Job:"教师");

  • 命名参数可以调换顺序,但是得保证有默认值的参数必须放在无默认值的参数之后,否则会产生编译错误。

         image

注意:如果参数中存在数组参数,这个规则不成立。因为数组参数没有默认值,也要放到参数列表的最后。

  • 默认值必须是编译时就能确定的值。例如基元类型、枚举类型、能设为Null的引用类型等。经常将默认值设置为相应的零值,可以使用关键字default、new来实现。
  • 含有ref或Out关键字的参数不能设置默认值,会产生编译错误。因为这些参数不好设置有意义的默认值

二、 引用方式传参—Out, Ref

CLR假定方法的参数是以传值方式进行的,但它允许以传引用的方式传递参数。C#通过Out和ref关键字可以传递指向实例的一个指针,而不是参数本身的值。

Out和Ref的使用区别:

  • Out: 在调用之前不必初始化参数值;   被调用的方法内部不能读取参数值;        返回之前必须为该参数赋值。
  • Ref:  调用之前必须初始化参数值;      被调用方法可以读取或者写入参数的值;  返回之前可以不为该参数赋值(不考虑程序实际意义)。
1. 值类型使用Out和Ref

image

运行结果:

image

相应的IL元数据:

image

2. 引用类型使用out和ref

当调用方法时,如果形参类型为实参类型的基类,一般会发生隐式转换。例如:

public static void Swap(object a, object b)
       {
           object t = a;
           a = b;
           b = t;
       }

          string a = "AAA", b = "BBB";
          Swap(a, b);
          Console.WriteLine("a=" + a + " b=" + b);

     image

但是运行结果并非我们所愿,因为方法默认是以传值方式传递参数的,调用后原来的值是不会改变的。

当以传引用的方式向方法传递参数时,必须保证变量类型与方法签名中类型一致,而不能自动进行隐式转换,否则会产生编译错误。例如:

public static void Swap(ref object a, ref object b)
      {
          object t = a;
          a = b;
          b = t;
      }

    image

为了实现想要的效果,我们可以采用泛型

public static void Swap<T>(ref T a, ref T b)
       {
           T t = a;
           a = b;
           b = t;
       }

static void Main(string[] args)

{

string a = "AAA", b = "BBB";

Swap(ref a, ref b);

Console.WriteLine("a=" + a + " b=" + b);

Console.Read();

}

image

3. 重载

在C#中,可以使用Out或者ref关键字进行方法重载,例如下面的例子是合法的:

image

image

但是如果两个方法名称和参数相同,仅通过out和ref关键字是不能算作重载的。

image

image

、 可变数量参数传递—Params

某些时候,我们希望方法参数的个数是可变的,Params帮我们实现了这个想法。

实例

image

image

假如不使用Params关键字,我们需要使用第①种调用方式。当添加Params关键字后,我们可以采用②③,调用方式看上去更加直观了。实现了传递可变数量参数的效果。

注意事项:
  • Params关键字参数只能放在参数列表的最后,如果调换上面例子中两个参数位置,会产生编译错误。

          image

  • Params关键字只能标识任意类型的一个一维数组。
  • Params参数允许为Null值或者长度为0的数组。例如上面例子中的④⑤。
  • Params方式其实会造成一些性能损失,例如在堆上为数组分配内存、数组初始化等,所以尽量不要过多使用变长参数。





    本文转自 陈敬(Cathy) 博客园博客,原文链接:http://www.cnblogs.com/janes/archive/2011/08/09/2131163.html ,如需转载请自行联系原作者

相关文章:

  • iOS安全系列之 HTTPS
  • 解决ssh免密码登录仍然提示输入密码问题
  • [改善Java代码]使用Throwable获得栈信息
  • VMM系列之VMM服务器主机和主机组介绍
  • JavaScript内置对象(二)
  • 私有网盘nextcloud 12的使用介绍
  • win10使用Composer-Setup安装Composer以及使用Composer安装Yii2最新版
  • 面试
  • 深入浅出——float
  • 为Docker配置阿里加速器,系统为Debian8
  • 利用Scikit-Learn和Spark预测Airbnb的listing价格
  • H264中的SPS、PPS提取与作用转
  • 4G VoLTE存在漏洞可导致手机用户地理位置和其它个人信息泄露
  • Java框架搭建-Maven、Mybatis、Spring MVC整合搭建
  • 突破你的想象 OPPO R11s新升级
  • 【翻译】Mashape是如何管理15000个API和微服务的(三)
  • 2017 年终总结 —— 在路上
  • DOM的那些事
  • ECMAScript6(0):ES6简明参考手册
  • input的行数自动增减
  • Java多态
  • Linux下的乱码问题
  • spring boot 整合mybatis 无法输出sql的问题
  • Vultr 教程目录
  • 工作手记之html2canvas使用概述
  • 聊聊redis的数据结构的应用
  • 如何在GitHub上创建个人博客
  • 实习面试笔记
  • 怎么把视频里的音乐提取出来
  • nb
  • puppet连载22:define用法
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • ​LeetCode解法汇总2808. 使循环数组所有元素相等的最少秒数
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • (JS基础)String 类型
  • (简单) HDU 2612 Find a way,BFS。
  • (离散数学)逻辑连接词
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (原創) 如何安裝Linux版本的Quartus II? (SOC) (Quartus II) (Linux) (RedHat) (VirtualBox)
  • (转)Oracle存储过程编写经验和优化措施
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .net 写了一个支持重试、熔断和超时策略的 HttpClient 实例池
  • .NET框架
  • .Net中的集合
  • @param注解什么意思_9000字,通俗易懂的讲解下Java注解
  • [100天算法】-目标和(day 79)
  • [1181]linux两台服务器之间传输文件和文件夹
  • [20190401]关于semtimedop函数调用.txt
  • [C++]:for循环for(int num : nums)
  • [Editor]Unity Editor类常用方法
  • [EULAR文摘] 脊柱放射学持续进展是否显著影响关节功能
  • [Excel] vlookup函数