《CLR via C#》设计类型.参数

9.参数

9.1可选参数和命名参数

有默认值的参数就是可选参数,调用有可选参数的方法时,可以选择不提供部分实参。在形参列表里:可选参数必须在所有必需参数(比如weight)后。

static void Main(string[] args)
{
    Param(145.5f, "jump", 170.5f);
    Console.ReadKey();
}
static void Param(float weight, string name = "jump", float height = 180.1f) 
{
    Console.WriteLine("name = {0}, height = {1}, weight = {2}", name, height, weight);
}

假设你要传递weight实参,那么你在调用时,就不能跳过传递height实参。但是,命名参数就允许你这样做:Param(145.5f, height: 170.5f);在实参列表里:命名参数必须在所有必需参数(比如weight)后。
可选参数的实现原理:C#编译器自动给可选参数应用一个可选特性和一个默认参数值特性,这两个特性都会存在元数据里,然后,会向默认参数值特性的构造器传递你指定的默认值,这样,编译器就可在你不提供部分实参时,从元数据中提取默认值并将值嵌入调用中。

9.2var只能声明方法内的局部变量

var根据右侧表达式推断出类型,var的主要作用:复杂类型能少打一些字。注意:不能用var声明参数,不能用var声明类型中的字段。

9.3以传引用的方式向方法传递参数

CLR默认所有方法参数都传值,C#提供了out和ref支持传引用。out:不用在调用方法前初始化out参数,也不能在方法中读取out参数的值,但必须在return前初始化out参数,out主要用于得到额外的“返回值”;ref:必须在调用方法前初始化ref参数,可以在方法中读或写ref参数的值。

对值类型和引用类型使用out和ref没啥区别,都是传的引用。

9.4向方法传递可变数量的参数

应用举例:String类型的一些方法就需要允许连接任意数量的字符串。

// 个数可变的参数
static void VariableCount(params int[] values)
{
    int i = 0;
    foreach(int value in values)
    {
        Console.WriteLine(values[i++] + " ");
    }
}

// 个数可变和类型可变的参数
static void VariableCountAndType(params Object[] objects)
{
    foreach(Object obj in objects)
    {
        Console.WriteLine(obj.GetType());
    }
}

// 在Main里:
VariableCount(new int[] { 1, 4, 7, 3, 6, 9 });
VariableCount( 1, 4, 7, 3, 6, 9 ); // 和上一行等价,因为params告诉编译器向参数应用了一个特性,帮你new了
VariableCountAndType(new Object[] { 1, "4", 7, "jump" });
VariableCountAndType(1, "4", 7, "jump" ); // 和上一行等价

注意:params只能用于最后一个参数。

参数数量和类型可变对性能都有不小的影响,要减少影响可考虑定义几个没有使用params的重载版本,以System.String类的Concat方法为例:

public static String Concat(object arg0, object arg1);
public static String Concat(object arg0, object arg1, object arg2);
public static String Concat(params object[] args); // 使用了params重载不常用的情形
public static String Concat(String str0, String str1);
public static String Concat(String str0, String str1, String str2);
public static String Concat(params String[] values); // 使用了params重载不常用的情形

9.5参数和返回类型的设计规范

参数类型还可以是泛型接口等,见书P197 P198

猜你喜欢

转载自blog.csdn.net/BillCYJ/article/details/90650563