跟小静读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 ,如需转载请自行联系原作者
相关文章
|
6月前
|
存储 编解码 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用UserSet功能保存和载入相机的各类参数(C#)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用UserSet功能保存和载入相机的各类参数(C#)
84 0
|
5月前
|
存储 Java 编译器
C# 变量与参数详解
C# 变量与参数详解
|
6月前
|
开发框架 小程序 .NET
C#动态生成带参数的小程序二维码
C#动态生成带参数的小程序二维码
|
6月前
|
存储 C#
C# 方法详解:定义、调用、参数、默认值、返回值、命名参数、方法重载全解析
方法是一段代码,只有在调用时才会运行。 您可以将数据(称为参数)传递给方法。 方法用于执行某些操作,也被称为函数。 为什么使用方法?为了重用代码:定义一次代码,然后多次使用。
96 0
|
11月前
|
C# 数据安全/隐私保护
C# 窗体之间参数互相传递的两种方法与使用
C# 窗体之间参数互相传递的两种方法与使用
|
存储 API C#
Baumer工业相机堡盟工业相机如何通过文件保存和导入的方式保存和载入相机的各类参数(C#)
Baumer工业相机堡盟工业相机如何通过文件保存和导入的方式保存和载入相机的各类参数(C#)
79 0
|
存储 编解码 开发工具
Baumer工业相机堡盟工业相机如何通过BGAPI SDK使用UserSet功能保存和载入相机的各类参数(C#)
Baumer工业相机堡盟工业相机如何通过BGAPI SDK使用UserSet功能保存和载入相机的各类参数(C#)
60 0
|
数据挖掘 编译器 C#
【C#本质论 五】方法和参数
【C#本质论 五】方法和参数
67 0
|
数据处理 C#
基于C#的ArcEngine二次开发39:GP工具的使用--界面、参数及示例代码
基于C#的ArcEngine二次开发39:GP工具的使用--界面、参数及示例代码
基于C#的ArcEngine二次开发39:GP工具的使用--界面、参数及示例代码