- 引用类型作为值类型传递,形参和实参其实是两个指针,只不过指向的是同一块内存。新
new
一个对象是,它们两的联系就被切断了,指向了不同的内存块。 - 引用类型作为引用参数,此时的形参其实是实参的一个别名,它们两个其实是一个指针,新
new
一个对象是,指向的还是同一内存块,因为它们本身就是同一个指针。
两种情况的最后指向是不一样的。
以下情况是, 在方法内创建一个新对象并赋值给形参。
引用类型作为值参数
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();
}
}
}
输出:
原始值:20
=======
修改值之后:50
新创建之后:20
=======
最后值:50 // 被修改
引用类型作为引用参数
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();
}
}
}
输出:
原始值:20
=======
修改值之后:50
新创建之后:20
=======
最后值:20 // 是新 new 对象的默认值 20
如果不在方法内部改变引用形参的指向,他们操纵的内存区域是一样的,结果也是一样的。
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();
}
}
}
输出:
调用前:a = 10, b = 20
调用后:a = 15, b = 20 // 可见 对象a的数值成员值改变了,值变量b没有改变。
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();
}
}
}
输出:
调用前:a = 10, b = 20
调用后:a = 15, b = 25 // 可见 都改变了。
参考: 《C#图解教程》 -> P66