如何触及方法内部申明的变量
时间:2010-08-24 来源:芥子-dancingbit
经常混CSDN,免不了碰上一些稀奇古怪的问题:http://topic.csdn.net/u/20100823/16/fcb0b431-eeb6-4ab1-9e05-aba2eb01fe46.html,从一个方法的外部访问方法内部的变量,看到标题的第一眼,我的第一个想法就是:不可能。然后,鉴于CSDN上经常有人提问时辞不达意(写完了我要说的话,回头看看,我自己也是同样的辞不达意),我还是决定打开看看,顺便看看提问者有没有排除返回值的可能。最后,提问者应该是认可了ref或out的说法,琢磨来琢磨去,我始终觉得有点不对味。一直到睡觉时,还在想这个问题。
其实这个时候,我自己已经排除了返回值,并非由于提问者的不认可,在我的概念中,ref和out与返回值并无本质的不同,我思考的是:不管是哪种方式,我们真的能触及方法内部申明的变量么?答案是否。
事实上这里还有一个变量与它的值的区别,我们使用变量作为一个标识,代表我们在程序中使用的某个值,然而变量并不是这个值,同一个变量,可以在不同的时刻代表不同的值,而值本身并不会变化,不管它有没有被某个变量所代表,那个值还是那个值。弄清楚了这个区别,这个问题就应该不难理解了。不管是返回值也好,ref或out也好,我们触及的都是变量在那个时刻所代表的值,返回值,在返回前的那一刻将变量代表的值压入调用栈,其实是复制了那个值,变量本身在被调用方法结束以后就消亡了,我们在调用方法中使用的是那个值,复制以后的,当然还是那个值,但不是那个变量。对于ref或out来说,这个复制过程就更明显了,你甚至需要显式的操作。
如果说,对于值类型来说,这个变量与它所代表的值的区分还好理解一些的话,那么对于引用类型,这个区别就不是那么容易弄清楚了。引用类型,存在三个概念:对象本身,对此对象的引用,变量。我们通过引用来触及对象,使用变量代表引用。我们对引用类型的变量赋值,本质上是复制引用的值,不是它引用的对象的值,由此而导致多个引用(名词)引用(动词)同一对象,也经常由此导致初学者对于引用类型赋值的结果产生迷惑。举例来说,我们创建对象objA,同时将它赋给变量A,此时A代表一个引用,它引用了objA,如果再执行赋值B=A,实际上是把A(代表的引用)的值复制给B(代表的引用),然后这两个引用具有相同的值,因此引用了同一对象(实际上可能有更复杂一些,这里只是简化的描述)。回到我们的初始问题,在一个方法内部,如果我们申明的变量是一个引用类型的变量,那么,作为返回值时,被压入调用栈的,仍然是它的值(这一时刻,平白多了一个引用(名词)引用(动词)同一个对象),如果把它赋给ref或out修饰的参数,仍然是复制,显式的。
不管怎么说,我们在一个方法外部,无论如何,能访问到的,只能是那个变量在那个时刻代表的值而非变量本身,这是我的结论。辞不达意,权作抛砖。