1.值参数和引用参数:
在不考虑 ref 和 out 修饰的情况下,传递值类型的参数就是值参数,参数在方法中的修改不会保留;
传递引用类型的参数就是引用参数,参数在方法中的修改都会保留(在不为该引用参数重新赋值或实例化的前提下,参数在方法中的修改才会保留,否则一样不保留)。
public ActionResult Index() { int i = 0; TestMethod1(i); // 此时这里的i还是0,因为int是值类型。 TestClass tc = new TestClass(); tc.i = 0; TestMethod2(tc); // 此时这里的tc.i变为1,因为TestClass是引用类型。 tc.i = 0; TestMethod3(tc); // 此时这里的tc.i仍为0,因为TestClass虽然是引用类型,但在方法中已经重新实例化对象,跟之前的tc对象已经不是同一个了。 return View(); } private void TestMethod1(int i) { i = 1; } private void TestMethod2(TestClass tc) { tc.i = 1; } private void TestMethod3(TestClass tc) { tc = new TestClass(); tc.i = 1; } class TestClass { public int i { set; get; } }
按值传递参数相当于就是把参数复制了一份传到方法里面去,而复制品怎么改变都不会影响样品;同样,按引用传递参数后,在方法里重新实例化也相当于复制。
那么是不是传递值类型参数就不能改变方法外的变量了呢,不是,我们把值参数变成引用参数就可以了。只需要在值类型参数前面加上ref(引用参数)修饰,那么本该是值参数就会变成引用参数(参数本身还是值类型):
public ActionResult Index() { int i = 0; TestMethod4(ref i); //参数必须是变量,传参前要赋值。 // 此时这里的i变为1了,加了ref关键字。 return View(); } private void TestMethod4(ref int i) { i = 1; }
2.out(输出参数):
必须在声明和调用中都使用 out 修饰符(ref 也是同样)。
public ActionResult Index() { string msg1, msg2; bool whether = TestMethod5(out msg1, out msg2); // 得到msg1为"张三执行",msg2为"成功" return View(); } private bool TestMethod5(out string msg1, out string msg2) { msg1 = "张三执行"; msg2 = "成功"; //在方法中必须要初始化赋值 return true; }
out(输出参数)适合用在需要 retrun 多个返回值的地方;而 ref(引用参数)则用在需要被调用的方法修改调用者的引用的时候。
out 和 ref 的区别:https://www.cnblogs.com/Allofus/p/14774691.html
3.params(数组参数):
- 在一个参数列表中只能有一个参数数组
- 如果有,它必须是列表中的最后一个
- 不允许将 params 修饰符与 ref 和 out 修饰符组合起来使用
- 数组是一个引用类型,因此它的所有数据项都保存在堆中
public ActionResult Index() { int[] arr = { 1, 2, 3, 4, 5, 6 }; int[] b = TestMethod6(arr); return View(); } private static int[] TestMethod6(params int[] arr) { return arr; }
4.可选参数:
可选参数是 .NET4 中新添加的功能,应用可选参数的方法在被调用的时可以选择性的添加需要的参数,而不需要的参数由参数默认值取代。
public ActionResult Index() { int i = 0; string s1 = TestMethod7(i); //结果为"0是失败" string s2 = TestMethod7(i, "是成功"); //结果为"0是成功" return View(); } private string TestMethod7(int i, string str = "是失败") { return i + str; }
5.命名参数:
命名参数是把参数附上参数名称,这样在调用方法的时候不必按照原来的参数顺序填写参数,只需要对应好参数的名称也能完成方法。
public ActionResult Index() { string s = TestMethod8(str: "是成功", i: 0); //结果为"0是成功" return View(); } private string TestMethod8(int i, string str) { return i + str; }
命名参数如果只是改变参数的顺序,这样的意义并不大,我们没有必要为了改变顺序而去用命名参数,他与可选参数结合才能显示出他真正的意义。
public ActionResult Index() { int i= 0; string s = TestMethod9(i, str2: "失败"); //结果是"0张三执行失败" return View(); } private string TestMethod9(int i, string str1 = "张三执行", string str2 = "成功") { return i + str1 + str2; }
参考:https://zhidao.baidu.com/question/2011292093902737868.html
https://www.cnblogs.com/weiming/archive/2011/12/28/2304937.html