我昨天遇到了问题,希望大神帮我看看,具体该怎么理解
在try中,遇到了return,那么这个值就定死了。如果是引用类型,那么这个地址也就定死了。然后再去执行finally里面的代码,如果是引用类型,那么在地址定死的情况下,更改引用类型内部的值,是可被接受的改变。然后为什么返回的list.Count=2,因为list.Count本身是值类型,finally里面虽然修改了list,但是,只要记住,遇到return,那么返回值(不管什么类型,返回值都可以看成值,只不过如果是值类型,那么就是本身,如果是引用类型,就是这个引用的地址)就定死了。
1 public MyClass TestTryMethod() 2 { 3 var myClasses = new MyClass(); 4 5 try 6 { 7 myClasses.index = 1; 8 myClasses.str.Add("aaa"); 9 return myClasses; 10 } 11 catch (Exception exception) 12 { 13 } 14 finally 15 { 16 myClasses.index = 2; 17 myClasses.str.Add("bbb"); 18 } 19 return myClasses; 20 } 21 class MyClass 22 { 23 public int index; 24 public List<string> str = new List<string>(); 25 }
哥啊,您老认为最后调取这个方法的答案是神马
@代码小兵的成长: 你确实不知道执行顺序,而且还分不清值类型和引用类型,你把 class MyClass 换成 struct MyClass 试试。
@Launcher: 额,换成struct又变化了,我已经彻底搞晕了
@Launcher: 我今天先把内存咋分配的机制搞出来吧,不是我不知道执行顺序,也能分清值类型引用类型,而是对一个类里面或者数组里面同时含有值类型引用类型咋处理的比较好奇,我觉得自己的 差距在内存这块
@代码小兵的成长: 结果是index=2,然后里面有2个元素啊。在L9,遇到return,所以返回这个对象的内存地址(引用类型),然后finally里面的改变影响该对象(引用类型内存地址不变,那内部的对象也可能变化的,存储在堆上的嘛,栈上一个指针指向它)。
@幻天芒: 大神,学习了一些堆栈的知识,其他的都能理解,就是如果把class换成struct,最后的结果返回是index = 1;然后有两个元素,这个没搞太懂,是不是因为struct对象在声明的时候存放在栈中,而struct实体里面的index也放在栈中,List<string>对象却在栈中存放的是一个地址而已
@代码小兵的成长: 你的理解是对的。struct存储在栈上,当然引用的话,还是存的地址。
也就是说你还是不知道 try-catch-finally 的执行顺序?
这个顺序还算理解吧,我毕竟一步步走下去的,只不过对它的返回值有点疑问而已
@代码小兵的成长: 你确实不知道执行顺序,而且还分不清值类型和引用类型,你把 class MyClass 换成 struct MyClass 试试。
并且,你还不仔细,一步一步走下去时,最后一条 return myClasses 根本没执行过;你也不管警告,典型的程序员思维,你的 catch (Exception exception) 就是没用的代码,release 下直接就给你优化掉了。你在 catch (Exception exception) 添加 return myClasses 语句试试,你会发现编译器会警告你最后一条 return myClasses 语句是无法访问的代码。
最后你根本不知道第一条 return myClasses 语句执行时到底发生了什么。
@Launcher: 我知道最后一个return不会执行的,至于catch,我只是摆在那里没管它,因为我测试的是try finally里面的数据,而且我测试过catch参与操作的情况。最后,我可能真的不理解,我今天再学习一下看看
值引用和对象引用的差别
多谢大神,我学习了一下堆栈的知识,发现确实是值类型引用类型在内存中不同位置的原因