public class Box
{
private int a = 10 ; public Box()
{
object aa = a ; this.chang( aa ) ; Console.WriteLine( aa ) ;
} public void chang( object aa )
{
aa = 34 ;
} }我的理解是按引用传后,运行结果为34,但其实结果仍为10,请高手解释。谢了。

解决方案 »

  1.   

    我是一个菜鸟,在学习装箱知识的时候,看到你的帖子,也很奇怪。
    经过思考,基本上理解了原因,陈述如下:首先将你的程序修改一下,增加一下测试
    using System;
    class Tester {
    public static void Main()
    {
    Box a = new Box();
    }
    }
    public class Box
    {
    private int a = 10 ;
    private object aa; // 为了便于object对象的比较public Box()
    {
    aa = a ;this.chang( aa ) ;Console.WriteLine( aa ) ;
    }public void chang( object aa )
    {
    Console.WriteLine("重新赋值前对象是否相等:" + this.aa.Equals(aa).ToString());
    aa = 34 ;
    Console.WriteLine("重新赋值前对象是否相等:" + this.aa.Equals(aa).ToString());
    }}注意观察,aa=34前后的变化。你会发现重赋值前,参数aa 是等于 对象的私有变量this.aa的;但在复制后参数aa不再等于私有变量this.aa了,所以参数的重赋值不起作用。那为什么重赋值会导致不相等了呢,原因是C#中参数是传值的,也就是拷贝的,虽然在这里它拷贝的只是一个指针。但是这个指针(也就是参数aa)和以前(私有变量this.aa)的指针不再是同一个指针了,他们的关系只是指向同一托管堆地址。由于开始指向同一托管堆,也就是指针内容相同,所以重赋值前两个指针Equals相等。重赋值(aa=34)的动作实际上是将参数(aa)的指针内容重新更改,使其指向另一个托管堆地址。(34是一个字面值,这里也存在一次34的装箱,用ildasm查看可发现)这下明白了,由于参数只是拷贝了指针,而重赋值导致拷贝的指针变化,而不是原指针的变化,所以重赋值无效。