为什么注释前后输出不同?

wzp144650 2011-04-26 10:08:30

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的堆?
...全文
250 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
vrhero 2011-04-26
  • 打赏
  • 举报
回复
这还是.NET方法参数默认按值传递的问题...去看这个...

【.NET版月经问题】之二【引用类型参数就是按引用传递吗?】
Icedmilk 2011-04-26
  • 打赏
  • 举报
回复
如果用了ref

你在MyFunction中操作的a就是Main中的a,其实你可以不考虑地址的问题。

如果牵扯到地址,理解起来就很费劲。
wzp144650 2011-04-26
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 icedmilk 的回复:]

你给出的代码与ref和out没有半点关系

引用 20 楼 wzp144650 的回复:
引用 18 楼 icedmilk 的回复:

首先,您能理解注视后只有一个对象而注释前有两个对象吗?

引用 15 楼 wzp144650 的回复:
如果是堆地址的话,那么,注释后也同样是改变对地址呀


我不想被鄙视!我觉得你应该考虑你是否有我想的全面
[/Quote]

是啊,是跟ref没有关系,但是应该想到ref时是什么情况!
Icedmilk 2011-04-26
  • 打赏
  • 举报
回复
你给出的代码与ref和out没有半点关系

[Quote=引用 20 楼 wzp144650 的回复:]
引用 18 楼 icedmilk 的回复:

首先,您能理解注视后只有一个对象而注释前有两个对象吗?

引用 15 楼 wzp144650 的回复:
如果是堆地址的话,那么,注释后也同样是改变对地址呀


我不想被鄙视!我觉得你应该考虑你是否有我想的全面
[/Quote]
seraphgxh 2011-04-26
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 wzp144650 的回复:]

恩恩,我说错了,改变的是堆中的值,我是想说,两种情况都是改变了堆。

我说说我的看法吧,其实我觉得作为参数传进来,其实传的是a的堆地址,注释前由于试图去改变a堆地址,将其指向b的堆,所以方法执行完后,对main函数中的a没有影响,应为a的堆内容没有变。
注释后直接更改了a堆的内容,所以main中有影响

如果加ref 传进来,则传的是栈地址,不管是改变堆地址还是改变堆内容传出去后都会影……
[/Quote]

同意
wzp144650 2011-04-26
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 icedmilk 的回复:]

首先,您能理解注视后只有一个对象而注释前有两个对象吗?

引用 15 楼 wzp144650 的回复:
如果是堆地址的话,那么,注释后也同样是改变对地址呀
[/Quote]

我不想被鄙视!我觉得你应该考虑你是否有我想的全面
wzp144650 2011-04-26
  • 打赏
  • 举报
回复
恩恩,我说错了,改变的是堆中的值,我是想说,两种情况都是改变了堆。

我说说我的看法吧,其实我觉得作为参数传进来,其实传的是a的堆地址,注释前由于试图去改变a堆地址,将其指向b的堆,所以方法执行完后,对main函数中的a没有影响,应为a的堆内容没有变。
注释后直接更改了a堆的内容,所以main中有影响

如果加ref 传进来,则传的是栈地址,不管是改变堆地址还是改变堆内容传出去后都会影响a
Icedmilk 2011-04-26
  • 打赏
  • 举报
回复
首先,您能理解注视后只有一个对象而注释前有两个对象吗?

[Quote=引用 15 楼 wzp144650 的回复:]
如果是堆地址的话,那么,注释后也同样是改变对地址呀
[/Quote]
seraphgxh 2011-04-26
  • 打赏
  • 举报
回复
有一点可能没说清楚,MyClass a = new MyClass();中的a是一个地址(也可以说是指针),而string类型的a才是地址中的值。
seraphgxh 2011-04-26
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 wzp144650 的回复:]

如果是堆地址的话,那么,注释后也同样是改变对地址呀
[/Quote]

注释后,没有改变地址,只改变了地址中的值。
注释前,有两个地址a和b, a=b把b的地址给了a (也可以说是指针a指向了b), 之后的操作改变的是地址b中的值,地址a中的值没有变。
wzp144650 2011-04-26
  • 打赏
  • 举报
回复
如果是堆地址的话,那么,注释后也同样是改变对地址呀
SmallBear 2011-04-26
  • 打赏
  • 举报
回复
seraphgxh 2011-04-26
  • 打赏
  • 举报
回复
改变的是堆的地址,因为用new申请的变量一般都在堆上
wzp144650 2011-04-26
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 seraphgxh 的回复:]

注释前,a = b把a指向了b, 下面的a.a = "b";其实改变的是b实例中的值,又因为传递参数是没有用ref所以实参的地址不会被改变,所以退出函数以后a实例中的a值还是"a";

注释后,把a 所指向的地址中的值被改成了"b",所以退出函数后值仍然是"b";
[/Quote]

你觉得a=b的过程是改变的是a堆的地址还是栈的地址呢
seraphgxh 2011-04-26
  • 打赏
  • 举报
回复
注释前,a = b把a指向了b, 下面的a.a = "b";其实改变的是b实例中的值,又因为传递参数是没有用ref所以实参的地址不会被改变,所以退出函数以后a实例中的a值还是"a";

注释后,把a 所指向的地址中的值被改成了"b",所以退出函数后值仍然是"b";
wzp144650 2011-04-26
  • 打赏
  • 举报
回复
认为之前的答案都不是想要的答案,还有更好的答案吗
Joop_Song 2011-04-26
  • 打赏
  • 举报
回复
你传入参数时,拷贝了一个a的副本,在方法里面对副本进行操作。。。

外边还是原来的a。。。。
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 icedmilk 的回复:]
[/Quote]
传递参数时候,拷贝的仅仅是引用,实参和形参虽然是不同的引用,但指向的是同一个MyClass对象

难道是这样?
因为第一个形参的引用地址被改变了,指向了b,跟实参地址不同,所以无法影响实参,而注释后因为地址还是同一个地址,所以形参变化会导致实参变化?
Icedmilk 2011-04-26
  • 打赏
  • 举报
回复
注释前你的代码涉及了两个对象,MyFunction里面改动的对象是新建的。

注释后你的代码就涉及了一个对象,MyFunction里面操作的就是那个唯一的对象


传递参数时候,拷贝的仅仅是引用,实参和形参虽然是不同的引用,但指向的是同一个MyClass对象
wzp144650 2011-04-26
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 bdmh 的回复:]

第一种情况,MyFunction的a是不允许修改的,执行完MyFunction,a的值是不变的
[/Quote]

为什么第一种情况不允许变?为什么第二种情况允许变?
加载更多回复(12)

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧