关于C#装箱的疑问

段小江 2017-09-20 09:23:18
加精
int a = 1;
object b=a;
object c = b;
c = 2;
为什么b不会变成2呢?b和c应该指向堆里面的同一个引用啊?
...全文
7630 45 打赏 收藏 转发到动态 举报
写回复
用AI写文章
45 条回复
切换为时间正序
请发表友善的回复…
发表回复
大鱼> 2017-10-19
  • 打赏
  • 举报
回复
引用 4 楼 sp1234 的回复:
b 和 c 引用同一个 对象,然后给 c 赋值之后,c 引用新的对象了,而 b 还引用原来的对象。你看死读书有时候会反向理解内部机制,会误解一般人都能理解的机制。
就服你,原谅刚刚学习的孩子。当年刚刚学C++的时候我还不如他呢。
chunshuo 2017-10-19
  • 打赏
  • 举报
回复
b 复制给了c 又把C的值改成了2 但是b的值是不变的
Scorpio_TW 2017-10-13
  • 打赏
  • 举报
回复
前面有几位都说的很对。
关键就在最后一句
c = 2;
在这c是一个引用类型,而2不是一个引用类型,所以这里发生了装箱,c指向了一个新的对象,和之前的对象不再有任何关系。
{
.entrypoint
// Code size 20 (0x14)
.maxstack 1
.locals init ([0] int32 a,
[1] object b,
[2] object c)
IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: box [mscorlib]System.Int32
IL_0009: stloc.1
IL_000a: ldloc.1
IL_000b: stloc.2
IL_000c: ldc.i4.2
IL_000d: box [mscorlib]System.Int32
IL_0012: stloc.2
IL_0013: ret
}

2次装箱过程
njit_77 2017-10-07
  • 打赏
  • 举报
回复
引用 12 楼 impasse 的回复:
这么多大神,我只能出来说下自己的看法了,但不一定对. int a = 1; //a是栈里的数1 object b=a; //装箱b指向堆,堆里1 object c = b;//c栈里的地址指向b同地址 c = 2;//这里有错误,a,b,c都是1,只是b,c指向堆,a只有栈
我的看法与你一致,关于此贴。我把自己的观点写了出来,有空还请指导http://blog.csdn.net/njit_77/article/details/78168369
闭包客 2017-09-26
  • 打赏
  • 举报
回复
引用 29 楼 dy00544 的回复:
我还真的从来没用过object。 object现在还用得多么? 难道不是用泛型么。
的确,在实际项目中全部用泛型。
dy00544 2017-09-26
  • 打赏
  • 举报
回复
我还真的从来没用过object。 object现在还用得多么? 难道不是用泛型么。
删库到跑路 2017-09-26
  • 打赏
  • 举报
回复
学习喽
  • 打赏
  • 举报
回复
引用 5 楼 lovelj2012 的回复:
值类型,是直接存值
对的
JOHN2577 2017-09-22
  • 打赏
  • 举报
回复
你把值类型 2 赋给了Object类型的c,这里会发生新的装箱,c指向了新的对象
正怒月神 2017-09-22
  • 打赏
  • 举报
回复
引用 24 楼 youbl 的回复:
楼主的代码:
object b=a;
object c = b;
c = 2;
这里的c = 2,跟改成 c=new User()是一样的效果, 我建议可以这么理解,所有的变量本身都是值类型的,比如: object a = xxx; 这个a存储的是一个值类型的地址,修改这个a本身,对地址的指向没影响, 如果修改a.name,那么是修改地址指向的内容了,所以有影响 个人见解
这么说,其实也没什么问题。 因为值类型和引用类型到object,本来就是不一样的。
正怒月神 2017-09-22
  • 打赏
  • 举报
回复
引用 22 楼 youbl 的回复:
一样啊,楼主的也是变量本身的引用被改掉了, c跟b 不再指向同个地址了
这个问题的本质,我觉得还是值类型到object,和引用类型到object,存在的区别。 而你的代码b=new user()是导致引用断裂。 我想两者之间描述的情况有些不同。
正怒月神 2017-09-22
  • 打赏
  • 举报
回复
引用 20 楼 youbl 的回复:
这个问题跟装箱有毛关系啊 这个问题跟装箱有毛关系啊 这个问题跟装箱有毛关系啊 举个栗子,
var a = new User();
a.name = "xxx";
var b = a;
b=new User();
b.name = "ddd";
来来来,你告诉我,为什么a.name没变,还是xxx???
你的 b=new User(),是导致引用断裂了。 如果b=a的话,那改变b,a就会变。 楼主可能疑惑的是,值类型和引用类型到object的结果不同。
游北亮 2017-09-22
  • 打赏
  • 举报
回复
另一个例子有点类似:

var a=new User();
a.name = "111";
aaa(a); // a不受影响
bbb(a); // a被影响了,name变了

void aaa(User x){
  x = new User();
  x.name = "222";
}
void bbb(User x){
  x.name = "222";
}
游北亮 2017-09-22
  • 打赏
  • 举报
回复
引用 23 楼 hanjun0612 的回复:
这个问题的本质,我觉得还是值类型到object,和引用类型到object,存在的区别。 而你的代码b=new user()是导致引用断裂。 我想两者之间描述的情况有些不同。
楼主的代码:
object b=a;
object c = b;
c = 2;
这里的c = 2,跟改成 c=new User()是一样的效果, 我建议可以这么理解,所有的变量本身都是值类型的,比如: object a = xxx; 这个a存储的是一个值类型的地址,修改这个a本身,对地址的指向没影响, 如果修改a.name,那么是修改地址指向的内容了,所以有影响 个人见解
游北亮 2017-09-22
  • 打赏
  • 举报
回复
引用 21 楼 hanjun0612 的回复:
[quote=引用 20 楼 youbl 的回复:] 这个问题跟装箱有毛关系啊 这个问题跟装箱有毛关系啊 这个问题跟装箱有毛关系啊
你的 b=new User(),是导致引用断裂了。 如果b=a的话,那改变b,a就会变。 楼主可能疑惑的是,值类型和引用类型到object的结果不同。[/quote] 一样啊,楼主的也是变量本身的引用被改掉了, c跟b 不再指向同个地址了
游北亮 2017-09-22
  • 打赏
  • 举报
回复
这个问题跟装箱有毛关系啊 这个问题跟装箱有毛关系啊 这个问题跟装箱有毛关系啊 举个栗子,
var a = new User();
a.name = "xxx";
var b = a;
b=new User();
b.name = "ddd";
来来来,你告诉我,为什么a.name没变,还是xxx???
秋的红果实 2017-09-21
  • 打赏
  • 举报
回复
装箱、拆箱不要轻易使用,效率会降低不少 平时,能用short的地方就不用int;参与运算的数值,尽量要用一种数据类型,int,long混在一起就会影响效率
秋的红果实 2017-09-21
  • 打赏
  • 举报
回复
无论是存储在栈上还是堆上,值类型终究是值类型,其“存储方法是一样的” object b=a; object c = b; 是的,b、c有相同的引用,你想办法输出这个地址,我想一定相同!但是,你取b、c的,不同的值类型的值,怎么会一样? 在我看来,所谓装箱,就是将处理位置,从栈改到堆的不同,其他一样 个人愚见
xuzuning 2017-09-20
  • 打赏
  • 举报
回复
只需记住一个事实:向变量赋值就切断了该变量原来可能有的引用
impasse 2017-09-20
  • 打赏
  • 举报
回复
这么多大神,我只能出来说下自己的看法了,但不一定对.

int a = 1; //a是栈里的数1
object b=a; //装箱b指向堆,堆里1
object c = b;//c栈里的地址指向b同地址
c = 2;//这里有错误,a,b,c都是1,只是b,c指向堆,a只有栈

加载更多回复(14)

110,499

社区成员

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

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

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