• C# 方法中带默认值的参数


    设计一个方法的参数时,可为部分或全部参数分配默认值。然后,调用这些方法的代码可以选择不指定部分实参,接受其默认值。除此之外,调用方法时,还可通过指定参数名称的方式为其传递实参。以下代码演示了可选参数和命名参数的用法:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace ParameterInMethod
    {
        class Program
        {
            private static int s_n = 0;
            private static void M(int x = 9, string s = "A", DateTime dt = default(DateTime), Guid guid = new Guid())
            {
                Console.WriteLine("x={0},s={1},dt={2},guid={3}",x,s,dt,guid);
            }
    
            static void Main(string[] args)
            {
                // 1. 等同于M(9, "A", default(DateTime), new Guid());
                M();
    
                // 2. 等同于M(8, "X", default(DateTime), new Guid());
                M(8, "X");
    
                // 3. 等同于M(5, "A", DateTime.Now, new Guid());
                M(5, guid: Guid.NewGuid(), dt: DateTime.Now);
    
                // 4. 等同于M(0, "1", default(DateTime), new Guid());
                M(s_n++, s_n++.ToString());
    
                // 5. 等同于以下两行代码:
                // string t1 = "2"; int t2 = 3;
                // M(t2, t1, default(DateTime), new Guid());
                M(s: (s_n++).ToString(), x: s_n++);
    
                Console.ReadLine();
    
                //程序输出结果如下:
                /*
                 * x=9,s=A,dt=0001/1/1 0:00:00,guid=00000000-0000-0000-0000-000000000000
                 * x=8,s=X,dt=0001/1/1 0:00:00,guid=00000000-0000-0000-0000-000000000000
                 * x=5,s=A,dt=2012/5/31 10:34:28,guid=cdc348c3-6435-40ed-8e37-23d90f4f05ce
                 * x=0,s=1,dt=0001/1/1 0:00:00,guid=00000000-0000-0000-0000-000000000000
                 * x=3,s=2,dt=0001/1/1 0:00:00,guid=00000000-0000-0000-0000-000000000000
                 */
    
            }
        }
    }
    View Code

    如果调用时省略了一个实参,C#编译器会自动嵌入参数的默认值。
    在对 M 的第4个调用中 s_n 中的当前值(0)传给x,然后 s_n 递增。随后, s_n 的当前值(1)作为一个字符串传给 s, 然后继续递增到 2. 使用已命名的参数传递实参时,编译器仍然按从左到右的顺序对实参进行求值。
    在对 M 的第5个调用中, s_n 中的当前值(2)被转换成一个字符串,并保存到编译器创建的一个临时变量(t1)中。接着, s_n 递增到3,这个值保存到编译器创建另一个临时变量(t2)中。然后, s_n 继续递增到4. 最后调用M时,向它传递的实参一次是 t2,t1 一个默认DateTime 和 新建的guid。

    规则和原则:

        可以为方法、构构造器方法和有参属性(C#索引器)的参数指定默认值。还可为属于委托定义一部分的参数指定默认值。然后,在调用该委托类型的一个变量时,可以省略实参,以接受默认值。
        有默认值的参数必须在没有默认值的所有参数之后。换言之,一旦定义了一个有默认值的参数,它右边的所有参数也必须有默认值。例如在面前的 M 方法定义中,如果删除 s 的默认值(“A”),就会出现编译错误。但这个规则有一个例外:“参数数组”这种参数必须放在所有参数(包括有默认值的这些)之后,而且数组本身不能有一个默认值。
        默认值必须是编译时能确定的常量值。那么,能为哪些参数设置默认值呢?这些参数的类型可以是C#认定的基元类型。还可以包括枚举类型,以及能设为 null 的任何引用类型。对于任何值类型的一个参数,可将默认值设为值类型的一个实例,并让它的所有字段都包含零值。可以用 default 关键字或者 new 关键字来表达这个意思;两种语法将生成完全一致的IL代码。在 M 方法中设置 dt 参数和 guid 参数的默认值时,分别使用的就是这两种语法。
        注意不要重命名参数变量。否则,任何调用者如果以传参数名的方式传递参数,都必须修改它们的代码。例如,在前面的 M 方法声明中,如果将dt变量重命名为 dateTime,对 M 的第三个调用就会造成编译错误:error CS1739:"M" 的最佳重载没有名为“dt”的参数。
        如果参数用 ref 或 out 关键字进行了标识,就不能设置默认值。因为没有办法为这些参数传递一个有意义的默认值。
        C#不允许省略逗号之间实参,比如M(1, , DateTime.Now).因为会造成可读性的影响,程序员将被迫去数这些逗号。

  • 相关阅读:
    .NET 压缩解压库发布,支持进度查看
    WPF 蒙罩层 LoadingPage
    WPF如何用TreeView制作好友列表、播放列表
    WPF多线程UI更新——两种方法
    .NET责任链模式(混合单例模式,模板方法模式)-----制作与扩展能力验证
    .NET单例模式-------各种写法&&验证
    迭代器模式和组合模式混用
    正确理解DTO、值对象和POCO
    理解POCO
    VM
  • 原文地址:https://www.cnblogs.com/wisdo/p/4309198.html
Copyright © 2020-2023  润新知