赋值是值传递还是引用传递?

-汪帆- 2010-02-20 02:49:32
参数传值的情况下,值传递和引用传递很好理解也容易区分。那么赋值运算的时候是值传递还是引用传递呢?
为了测试我分别写了两个程序,在form中拖入label1和label2,textBox1和button1
程序1:

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();

this.label1.Text = this.label2.Text;
}

private void button1_Click(object sender, EventArgs e)
{
this.label1.Text = this.textBox1.Text;
}
}


在textBox1中输入123,点击button1,可以看到label1变成了123,label2没有变。
从结果上看,这应该是值传递。

程序2:

public partial class Form1 : Form
{
A a1 = new A();
A a2 = new A();

public Form1()
{
InitializeComponent();
a1 = a2;
}

private void button1_Click(object sender, EventArgs e)
{
a1.Message = this.textBox1.Text;
this.label1.Text = a1.Message;
this.label2.Text = a2.Message;
}
}

class A
{
private string message;

public string Message
{
get { return message; }
set { message = value; }
}
}

在textBox1中输入123,点击button1,可以看到label1和label2的值都变成了123。
从结果上看,这应该是引用传递了。

这是怎么回事?大侠们都来讨论下吧。
...全文
600 37 打赏 收藏 转发到动态 举报
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
-汪帆- 2010-02-20
  • 打赏
  • 举报
回复
引用 36 楼 starfd 的回复:
引用 22 楼 strwangfan 的回复:不浪费时间,公布答案了:程序1: this.label1.Text = this.label2.Text; 这是深拷贝,即new了一个值和this.label2.Text相同的对象传给this.label1.Text。传值后this.label1.Text和this.label2.Text是没有关联的,所以改变this.label1.Text的值,this.label2.Text是不会变的。 程序2: a1 = a2; 这是浅拷贝,即a2把自己的引用传给了a1,a1,a2引用同一个对象。所以改变a1的值,a2会跟着一起变。为什么是浅拷贝呢?因为A类没有实现ICloneable接口。如果我实现了ICloneable接口,就会产生和程序1一样的结果。 C# codeclass A : ICloneable {privatestring message;publicstring Message {get {return message; }set { message= value; } }#region ICloneable 成员publicobject Clone() { A a=new A(); a.Message=this.Message;return a; }#endregion }// 赋值改为a1= (A)a2.Clone();

对楼主已经无话可说。。。。。

为啥呢?我的解释不对?阁下有何高见?
  • 打赏
  • 举报
回复
引用 22 楼 strwangfan 的回复:
不浪费时间,公布答案了:
程序1:
this.label1.Text = this.label2.Text;
这是深拷贝,即new了一个值和this.label2.Text相同的对象传给this.label1.Text。
传值后this.label1.Text和this.label2.Text是没有关联的,所以改变this.label1.Text的值,this.label2.Text是不会变的。

程序2:
a1 = a2;
这是浅拷贝,即a2把自己的引用传给了a1,a1,a2引用同一个对象。
所以改变a1的值,a2会跟着一起变。
为什么是浅拷贝呢?
因为A类没有实现ICloneable接口。
如果我实现了ICloneable接口,就会产生和程序1一样的结果。
C# codeclass A : ICloneable
{privatestring message;publicstring Message
{get {return message; }set { message= value; }
}#region ICloneable 成员publicobject Clone()
{
A a=new A();
a.Message=this.Message;return a;
}#endregion
}// 赋值改为a1= (A)a2.Clone();


对楼主已经无话可说。。。。。
zldnjack 2010-02-20
  • 打赏
  • 举报
回复
什么乱七八糟的?


什么乱七八糟的?
  • 打赏
  • 举报
回复
其实综合看看13、14、22楼,你把问题从“值传递、引用传递”又偷换成“深拷贝、浅拷贝”了?!
-汪帆- 2010-02-20
  • 打赏
  • 举报
回复
引用 27 楼 sp1234 的回复:
你在第一句就说“那么赋值运算的时候是值传递还是引用传递呢?”。

可是后边第二个,不过玩了一个 a1=a2;这个语句的障眼法,然后就解释(何况丝毫没有解释出来)什么值传递、引用传递。

你的三个赋值运算明明机制一模一样,你却给判定前一个叫做值传递,后两个叫做引用传递。这自然让人认为你故意写个跑偏的代码啦。

我提问时不知道为什么,在问题中也没有解释任何东西。只不过是摆出结果而已,这位老兄的理解方式似乎和常人大不相同。
zhouing00 2010-02-20
  • 打赏
  • 举报
回复
[fly]顶[/fly]
whb147 2010-02-20
  • 打赏
  • 举报
回复
路过
继续围观

回复内容太短了!
zhouing00 2010-02-20
  • 打赏
  • 举报
回复
[move]新年好!赋值传递[/move]
tmoonlight 2010-02-20
  • 打赏
  • 举报
回复
啊 错了 下面的a1改成a2....
tmoonlight 2010-02-20
  • 打赏
  • 举报
回复
public Form1()
{
InitializeComponent();
a1 = a2;
}

在你执行红色代码的那一刻,下面的函数就都变成了这玩意了
private void button1_Click(object sender, EventArgs e)
{
a1.Message = this.textBox1.Text;
this.label1.Text = a1.Message;
this.label2.Text = a1.Message;
}
  • 打赏
  • 举报
回复
你在第一句就说“那么赋值运算的时候是值传递还是引用传递呢?”。

可是后边第二个,不过玩了一个 a1=a2;这个语句的障眼法,然后就解释(何况丝毫没有解释出来)什么值传递、引用传递。

你的三个赋值运算明明机制一模一样,你却给判定前一个叫做值传递,后两个叫做引用传递。这自然让人认为你故意写个跑偏的代码啦。

-汪帆- 2010-02-20
  • 打赏
  • 举报
回复
引用 24 楼 sp1234 的回复:
引用 20 楼 strwangfan 的回复:引用 17 楼 sp1234 的回复:如果你把C# codethis.label1.Text=this.textBox1.Text;this.label2.Text=this.textBox1.Text; 叫做值传递,而把C# codethis.label1.Text=this.textBox1.Text;this.textBox2=this.textBox1;this.label2.Text=this.textBox2.Text; 叫做引用传递,除了说你不懂“值传递、引用传递”概念,还能说什么呢?建议把C#基础学好,再来发表意见

string本来就是引用类型,而.net中对字符串拷贝本来就只是拷贝string的值。

你在问题中写的三个赋值语句,.net都是拷贝右边的字符串而已。而你煞有介事区分的所谓“值传递、引用传递”,却用右边a1=a2来给人说明什么叫做引用传递概念,不觉得这个故弄玄虚的局很无聊吗?

申明下:这个不是我故弄玄虚,发帖的时候我确实不明白程序1和程序2的结果为什么不同,只是自己后来弄明白了。
简单的一个赋值操作传递的到底是值还是引用,大家可能都忽略了这个问题,也许从来都没有觉得这是个问题。所以我觉得有必要发个帖出来给大家讨论下。
  • 打赏
  • 举报
回复
而.net中对字符串拷贝本来就只是拷贝string的值 --> 而.net中对字符串赋值本来就只是(特殊地)拷贝string的值(建立新对象)
  • 打赏
  • 举报
回复
引用 20 楼 strwangfan 的回复:
引用 17 楼 sp1234 的回复:如果你把C# codethis.label1.Text=this.textBox1.Text;this.label2.Text=this.textBox1.Text; 叫做值传递,而把C# codethis.label1.Text=this.textBox1.Text;this.textBox2=this.textBox1;this.label2.Text=this.textBox2.Text; 叫做引用传递,除了说你不懂“值传递、引用传递”概念,还能说什么呢?
建议把C#基础学好,再来发表意见


string本来就是引用类型,而.net中对字符串拷贝本来就只是拷贝string的值。

你在问题中写的三个赋值语句,.net都是拷贝右边的字符串而已。而你煞有介事区分的所谓“值传递、引用传递”,却用右边a1=a2来给人说明什么叫做引用传递概念,不觉得这个故弄玄虚的局很无聊吗?
-汪帆- 2010-02-20
  • 打赏
  • 举报
回复
引用 21 楼 lzsh0622 的回复:
引用 6 楼 strwangfan 的回复:自己已经弄明白了,有差不多正确的答案就结贴给分了引用 12 楼 strwangfan 的回复:不懂请不要瞎嚷嚷

楼主,你这样的回复不感觉很无聊吗?

你有答案了直接结贴完事,愿意分享贴出答案;不愿意分享,别人的答案你认为不对,也可以无满意结果结贴。 

你的提问,变成了考试,有意义吗。

我是想结贴给分,答案都不正确不知道给谁啊
-汪帆- 2010-02-20
  • 打赏
  • 举报
回复
不浪费时间,公布答案了:
程序1:
this.label1.Text = this.label2.Text;
这是深拷贝,即new了一个值和this.label2.Text相同的对象传给this.label1.Text。
传值后this.label1.Text和this.label2.Text是没有关联的,所以改变this.label1.Text的值,this.label2.Text是不会变的。

程序2:
a1 = a2;
这是浅拷贝,即a2把自己的引用传给了a1,a1,a2引用同一个对象。
所以改变a1的值,a2会跟着一起变。
为什么是浅拷贝呢?
因为A类没有实现ICloneable接口。
如果我实现了ICloneable接口,就会产生和程序1一样的结果。

class A : ICloneable
{
private string message;

public string Message
{
get { return message; }
set { message = value; }
}

#region ICloneable 成员

public object Clone()
{
A a = new A();
a.Message = this.Message;
return a;
}
#endregion
}

// 赋值改为
a1 = (A)a2.Clone();

lzsh0622 2010-02-20
  • 打赏
  • 举报
回复
引用 6 楼 strwangfan 的回复:
自己已经弄明白了,有差不多正确的答案就结贴给分了
引用 12 楼 strwangfan 的回复:
不懂请不要瞎嚷嚷


楼主,你这样的回复不感觉很无聊吗?

你有答案了直接结贴完事,愿意分享贴出答案;不愿意分享,别人的答案你认为不对,也可以无满意结果结贴。 

你的提问,变成了考试,有意义吗。

-汪帆- 2010-02-20
  • 打赏
  • 举报
回复
引用 17 楼 sp1234 的回复:
如果你把C# codethis.label1.Text=this.textBox1.Text;this.label2.Text=this.textBox1.Text;
叫做值传递,而把C# codethis.label1.Text=this.textBox1.Text;this.textBox2=this.textBox1;this.label2.Text=this.textBox2.Text;
叫做引用传递,除了说你不懂“值传递、引用传递”概念,还能说什么呢?

建议把C#基础学好,再来发表意见
段传涛 2010-02-20
  • 打赏
  • 举报
回复
值类型不能作为其它任何类型的基类型,因此不能向值类型中增加任何新的虚方法,更不该有任何抽象方法,所有的方法都是sealed的(不可重写);
• 未装箱的值类型分配在栈上而不是堆上,而栈又不是GC的地盘儿,因此GC根本不过问值类型变量的死活,一旦值类型变量的作用范围一过,它所占的内存空间就立即被回收掉,不劳GC亲自动手。
段传涛 2010-02-20
  • 打赏
  • 举报
回复
1. 值类型的数据存储在内存的栈中;引用类型的数据存储在内存的堆中,而内存单元中只存放堆中对象的地址。
2. 值类型存取速度快,引用类型存取速度慢。
3. 值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针或引用
4. 值类型继承自System.ValueType,引用类型继承自System.Object
5. 栈的内存分配是自动释放;而堆在.NET中会有GC来释放
C#中基本数据类型是值类型,结构也是值类型。而数组、类、接口、字符串都是引用类型。

值类型:简单类型、枚举类型和结构类型
简单类型分为:除字符串外的都是简单类型。有:整型(有符号和无符号数)、浮点(float、double)、字符(char)、高精度小数(decimal)和布尔
------------------------------------------------------------------------------
加载更多回复(17)

110,536

社区成员

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

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

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