读书笔记:参数传递的那些事
基础不可不知
何为形参,何为实参,看下图便知:
被忽略的可变数目参数
可变数目参数:params 关键字修饰的一维数组。以下为简单实例演示:
1 static void Main(string[] args)
2 {
3
4 ShowNumberSum("参数固定", 1, 2, 3);
5 ShowNumberSum("参数可变", 1, 2, 3, 4, 5);
6 Console.Read();
7 }
8
9 static void ShowNumberSum(string temp, int i, int j, int k)
10 {
11 Console.WriteLine("{0}的和是:{1}", temp, i + j + k);
12 }
13
14 static void ShowNumberSum(string temp, params int[] numbers)
15 {
16 int sum = 0;
17 foreach (int i in numbers)
18 {
19 sum += i;
20 }
21 Console.WriteLine("{0}的和是:{1}", temp, sum);
22 }
params关键字用法小结:
- params 修饰的关键字必须是一维数组
- params 可以修饰任何类型的参数数组,如果需要接受任何类型参数,参数可以这样写:params object[] o
- params 修饰的参数必须位于参数列表的最后一位,并且一个方法中只能使用一次
参数传递的艺术
根据值类型和引用类型的异同,参数传递总结为以下四种情况:
值类型参数按值传递
值类型参数按值传递其实传递的是值类型实例的一个拷贝,被调用方法操作的属于其本身的实例拷贝,因此是不会影响原来调用方法中的参数值
引用类型参数按值传递
引用类型参数传递其实传递的是对象地址的拷贝,这和值类型按值传递其实是相同的,传递的都是 "值",但引用类型传递的 "值"是引用地址。
所以在调用方法后引用的值向会发生改变,从而改变了原对象的指向,故原对象的值发生了改变。以下是简单实例代码:
class Program { static void Main(string[] args) { testCal tc = new testCal(); changvalue(tc); Console.WriteLine("mark:" + tc.number1); Console.Read(); } static void changvalue(testCal tc) { tc.number1 = "new value"; Console.WriteLine(tc.number1); } }
class testCal { public string number1; public testCal() { number1 = "testCal"; } }
string类型按值传递的特殊性
分析一下代码:temp 的值在方法调用后改变了吗?
class Program { static void Main(string[] args) { string temp = "value"; ChangeValue(temp); Console.Read(); } static void ChangeValue(string str) { str += "Change"; Console.WriteLine(str); } }
执行ChangeValue(temp);传递的实参的引用地址
过程 str += "+Change"; 在这里其实是生成了一个新的地址给str,新的地址指向的值为 "value+Change",整个过程并没有改变原来对象的引用地址
值类型参数和引用类型参数按引用传递
按引用传递,其实主要就是利用ref 和 out 关键字。这对“孪生”兄弟,作用都是一样的,但是有些许的差异。
ref:参数必须初始化
out:参数可以不初始化,可以为null,但是方法内必须对该参数完成初始化
CLR允许通过使用ref 和out 进行方法的重载 如下所示:
调用时:
但是不允许以下情况:
读《你必须知道的.NET》 5.3 参数之惑-传递的艺术 Page 167
我要一步一步往上爬
在最高点乘着叶片往前飞
任风吹干 流过的泪和汗
我要一步一步往上爬
等待阳光静静看着它的脸
小小的天有大大的梦想
我有属于我的天
任风吹干流过的泪和汗
总有一天我要属于我的天