在讲C#参数传递之前,我们先简单讨论下 c#中值类型和引用类型的定义以及区别,有助于我们更好的理解参数传递。 我们从内存的角度来简单讨论下值类型和引用类型的区别。我们都知道值类型存储在栈上,引用类型分别在栈和托管堆上。如下图: 我们通过例子来看下 值类型和引用类型存储结构不同有哪些区别: 定义一个类 (引用类型) 定义一个结构(值类型) 在控制台输出定义如下代码: 输出结果: 我们将类换成结构,在看看结果如何 定义代码: 输出结果: 我们会发现同样的代码 但是结果不一样,其实 每个变量 都有其堆栈,不同的变量不能共用一个堆栈地址。直接上图 由图 我们可以看出 对于值类型 stu2的age属性更改不会影响 stu1 对于引用类型 stu1 和stu2 在栈上的地址是不同的。stu1=stu2 。这是2个相等的变量 所以他们在托管堆上的引用地址是一样的。修改age 会对stu1 stu2都造成影响。所以 2种情况下输出结果会不一样。 明白这些 我们就很容易理解参数传递了。 关于参数传递 分按值传递 和按 引用传递 按值传递 分 值类型参数按值快递 和 引用类型参数按值传递 按引用传递分 值类型参数按引用传递 和引用类型参数按引用传递 在讲解参数传递之前 我们还要明白一个概念 形参和实参。 形参和实参的类型 个数 顺序 必须要完全匹配。 1、值类型参数按值传递: 输出 结果: 我们可以看出sum的值 并没有改变还是10. 我们通过图表来说明为什么会这样。我们知道值类型都是存储在栈上。 2、引用类型参数按值传递: 定义一个引用类型: 输出结果: 可以看出结果改变了 输出是21. 为什么会是这样呢,直接上图: 3、值类型按引用传递 输出结果: 可以看出 这次sum的 值改变了 不是 10 而是11. 这就是ref 关键字的神奇作用。ref在参数传递中到底起了什么作用呢,我们可以理解为ref 仅仅是一个地址。在文章前面我们提到过, 每个变量都有其堆栈,不同的变量不能共用一个堆栈地址。所以形参和实参在栈上的地址是不一样的。ref所起的作用我们可以简单的理解为他会记住实参的地址,当形参的值改变后,他会把值映射回 之前的实参地址。 4、引用类型按引用传递 在使用ref 的时候 调用方法一定要加上ref关键字 ,Add(int i) 和Add(ref int i)是构成方法的重载的。 在参数传递中 我们都使用ref 作为示例,那么out关键字 和ref 有什么区别呢。ref和out本质基本一样。唯一的区别就是一个是侧重于修改,一个侧重于输出。 这段代码中 我们使用ref 之前 先给 sum 赋了初始值,然后修改sum的值。如果我们使用out 可以先不给sum赋值。在方法内部赋值。 params 关键字 是数组类型的参数。可以指定在参数数目可变处采用参数的方法参数,在方法声明中的 params 关键字之后不允许任何其他参数,并且在方法声明中只允许一个 params 关键字。也就是说方法中如果有多个参数只允许有一个params参数,而且要放在方法的最后一个参数。 参见 MSDN示例: string 类型我们都知道是我们最常用的一种引用类型,那么sting类型的参数传递会是什么样的呢,我们可以自己试验一下,会发现string是很特殊的一个引用类型。后续我会继续讲解关于string类型。 不正之处 欢迎指正! 1 public class Student
2 {
3 public int Age { get; set; }
4
5 public void Say()
6 {
7 Console.WriteLine("我的年龄是:"+Age);
8 }
9 }
1 public struct StructStudent
2 {
3 public int Age { get; set; }
4
5 public void Say()
6 {
7 Console.WriteLine("我的年龄是:" + Age);
8 }
9 }
1 static void Main(string[] args)
2 {
3 Student stu1 = new Student { Age=20};
4 Student stu2 = new Student();
5 stu2 = stu1;
6 stu2.Age = 30;
7 stu1.Say();
8
9 stu2.Say();
10 }
1 static void Main(string[] args)
2 {
3 StructStudent stu1 = new StructStudent { Age = 20 };
4 StructStudent stu2 = new StructStudent();
5 stu2 = stu1;
6 stu2.Age = 30;
7 stu1.Say();
8 stu2.Say();
9 }
1 class Program
2 {
3 static void Main(string[] args)
4 {
5
6 string str = "da jia hao";
7 //str 是实际参数
8 SayHello(str);
9 }
10 //strMessage是 形式参数
11 public static void SayHello(string strMessage)
12 {
13 Console.WriteLine(strMessage);
14 }
15 }
1 static void Main(string[] args)
2 {
3 int sum = 10;
4 Add(sum);
5 Console.WriteLine(sum);
6 }
7
8 public static void Add(int i)
9 {
10 i++;
11 }
1 public class Student
2 {
3 public int Age { get; set; }
4 }
1 static void Main(string[] args)
2 {
3 Student stu = new Student { Age =20};
4 Add(stu);
5 Console.WriteLine(stu.Age);
6 }
7
8 public static void Add(Student stu)
9 {
10 stu.Age++;
11 }
1 static void Main(string[] args)
2 {
3 int sum = 10;
4 Add(ref sum);
5 Console.WriteLine(sum);
6 }
7
8 public static void Add(ref int i)
9 {
10 i++;
11 }
1 public class Student
2 {
3 public int Age { get; set; }
4 }
1 static void Main(string[] args)
2 {
3 Student stu = new Student { Age=20};
4 Add(ref stu);
5 Console.WriteLine(stu.Age);
6 }
7
8 public static void Add(ref Student stu)
9 {
10 stu.Age++;
11 }
static void Main(string[] args)
{
int sum = 10;
Add(ref sum);
Console.WriteLine(sum);
}
public static void Add(ref int i)
{
i++;
}
1 // cs_params.cs
2 using System;
3 public class MyClass
4 {
5
6 public static void UseParams(params int[] list)
7 {
8 for (int i = 0 ; i < list.Length; i++)
9 {
10 Console.WriteLine(list[i]);
11 }
12 Console.WriteLine();
13 }
14
15 public static void UseParams2(params object[] list)
16 {
17 for (int i = 0 ; i < list.Length; i++)
18 {
19 Console.WriteLine(list[i]);
20 }
21 Console.WriteLine();
22 }
23
24 static void Main()
25 {
26 UseParams(1, 2, 3);
27 UseParams2(1, 'a', "test");
28
29 // An array of objects can also be passed, as long as
30 // the array type matches the method being called.
31 int[] myarray = new int[3] {10,11,12};
32 UseParams(myarray);
33 }
34 }
深入理解C#之 参数传递 ref out params
原创
©著作权归作者所有:来自51CTO博客作者issweiqi的原创作品,请联系作者获取转载授权,否则将追究法律责任
View Code
View Code
View Code
View Code
View Code
View Code
View Code
View Code
View Code
View Code
View Code
View Code
下一篇:我的友情链接
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
[C#]浅析ref、out参数
转载把按引用传
C# ref out 引用类型 Code -
带你深入理解传递参数
传递参数ECMAScript中所有函数的参数都是按值传递的。
函数 传参 局部变量 按值传递 基本类型 -
Vue ref 深入理解
Vue 3 中的 ref 是一个强大而灵活的工具,它为我们提供了更简单和直观的方式来处理响应式数据。通过理解 ref 的原理和最佳实践,我们可以在
vue.js 前端 javascript 开发语言 ecmascript -
25深入理解C指针之---传递数组
深入理解C指针之---传递数组
深入理解C指针 数组 #include i++ 数据