C#引用类型作为值参数和引用参数

  1. 引用类型作为值类型传递,形参和实参其实是两个指针,只不过指向的是同意块内存。新new一个对象是,它们两的联系就被切断了,指向了不同的内存块。
  2. 引用类型作为引用参数,此时的形参其实是实参的一个别名,它们两个其实是一个指针,新new一个对象是,指向的还是同一内存块,因为它们本身就是同一个指针。

两种情况的最后指向是不一样的。

以下情况是, 在方法内创建一个新对象并赋值给形参。

引用类型作为值参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;

namespace RefParameter
{
class MyClass
{
public int test = 20;
}

class Program
{
static private void RefparameterTest( MyClass mc)
{
mc.test = 50;
Console.WriteLine("修改值之后:{0}", mc.test);
mc = new MyClass();
Console.WriteLine("新创建之后:{0}", mc.test);

}
static void Main(string[] args)
{
MyClass mc = new MyClass();
Console.WriteLine("原始值:{0}\n=======", mc.test);
RefparameterTest( mc);
Console.WriteLine("=======\n最后值:{0}", mc.test);
Console.ReadKey();

}

}
}

输出:

1
2
3
4
5
6
原始值:20
=======
修改值之后:50
新创建之后:20
=======
最后值:50 // 被修改

引用类型作为引用参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using System;

namespace RefParameter
{
class MyClass
{
public int test = 20;
}

class Program
{
static private void RefparameterTest(ref MyClass mc)
{
mc.test = 50;
Console.WriteLine("修改值之后:{0}", mc.test);
mc = new MyClass();
Console.WriteLine("新创建之后:{0}", mc.test);

}
static void Main(string[] args)
{
MyClass mc = new MyClass();
Console.WriteLine("原始值:{0}\n=======", mc.test);
RefparameterTest(ref mc);
Console.WriteLine("=======\n最后值:{0}", mc.test);
Console.ReadKey();

}
}
}

输出:

1
2
3
4
5
6
原始值:20
=======
修改值之后:50
新创建之后:20
=======
最后值:20 // 还是原来

如果不在方法内部翻遍引用形参的指向,他们操纵的内存区域是一样的,结果也是一样的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;


namespace RefTest
{
class Myclass
{
public int val = 10;
}


class Program
{

static void Mymethod(Myclass a, int b) // 看这里
{
a.val += 5;
b += 5;
}

static void Main()
{
Myclass a = new Myclass();
int b = 20;

Console.WriteLine($"调用前:a = {a.val}, b = {b}");

Mymethod(a, b); // 看这里
Console.WriteLine($"调用后:a = {a.val}, b = {b}");

Console.ReadKey();
}
}
}

输出:

1
2
调用前:a = 10, b = 20
调用后:a = 15, b = 20 // 可见 对象a的数值成员值改变了,值变量b没有改变。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;


namespace RefTest
{
class Myclass
{
public int val = 10;
}


class Program
{

static void Mymethod(ref Myclass a, ref int b) // 看这里
{
a.val += 5;
b += 5;
}

static void Main()
{
Myclass a = new Myclass();
int b = 20;

Console.WriteLine($"调用前:a = {a.val}, b = {b}");

Mymethod(ref a, ref b); // 看这里
Console.WriteLine($"调用后:a = {a.val}, b = {b}");

Console.ReadKey();
}
}
}

输出:

1
2
调用前:a = 10, b = 20
调用后:a = 15, b = 25 // 可见 都改变了。




参考:
《C#图解教程》 -> P66

感谢支持!