public class Program
{
static void Main(string[] args)
{
MyClass a = new MyClass();
a.a="A";
Console.WriteLine(a.a);
MyFunction(a); Console.WriteLine(a.a);
Console.Read(); } public static void MyFunction(MyClass a)
{
//MyClass b = new MyClass();
//b.a = "B";
//a = b; a.a = "b";
Console.WriteLine(a.a);
}
} public class MyClass
{
public string a = "";
}
注释前输出 A b A
注释后 A b b
a=b这句话 的过程是不是将a堆的指向指向了b的堆?
传递参数时候,拷贝的仅仅是引用,实参和形参虽然是不同的引用,但指向的是同一个MyClass对象
因为第一个形参的引用地址被改变了,指向了b,跟实参地址不同,所以无法影响实参,而注释后因为地址还是同一个地址,所以形参变化会导致实参变化?
你觉得a=b的过程是改变的是a堆的地址还是栈的地址呢
注释后,没有改变地址,只改变了地址中的值。
注释前,有两个地址a和b, a=b把b的地址给了a (也可以说是指针a指向了b), 之后的操作改变的是地址b中的值,地址a中的值没有变。
注释后直接更改了a堆的内容,所以main中有影响如果加ref 传进来,则传的是栈地址,不管是改变堆地址还是改变堆内容传出去后都会影响a
是啊,是跟ref没有关系,但是应该想到ref时是什么情况!
{
//MyClass b = new MyClass();
//b.a = "B";
//a = b; a.a = "b";
Console.WriteLine(a.a);
}这样前后就一样了
虽然这里的传递是引用传递,不用ref关键字,你修改属性是可以,但是修改传递的变量本身的指向就不行。调用方传递变量a给函数MyFunction,实际只是传递了那个变量a所指的地址,如果加了ref关键字,不但传所指地址,还传了a变量本身。因此你在函数中想要修改a变量的指向是无效的,函数中获得的a变量于调用方的a变量是2个变量,虽然指向了同一个地址,你把函数中的a变量的指向改变了,不会影响调用方的a变量的指向,结果预期所示。
不同之处在于,对形参赋值还是对形参属性赋值。
a = b; 对形参赋值(并不会修改实参的引用)
a.a = "b"; 对形参属性赋值(实参的属性被修改)