static void Main(string[] args)
        {
            A a = new A();
            a.i = 1;
            object o = 1;             Change(a); Change(o);            Console.WriteLine("object:{0}; A:{1}",
                ((int)o).ToString(),
                a.i.ToString());
        }        static void Change(object o)
        {
            o = 5;
        }        static void Change(A i)
        {
            i.i = 5;
        }
结果:// ------------------------
object:1; A:5引用类型做函数的参数在调用函数时传递的是实例的引用,因此在函数中对引用类型做改动会影响到函数生命期外。
但是在将一个值类型装箱后同样的操作缺得到了不同的结果。在这个问题上对clr的处理机制感到迷惑,请高手指点

解决方案 »

  1.   

    上面代码忘了个class A    public class A
        {
            public int i;
        }
      

  2.   

    难道说clr判断出object引用的是一个值类型,所以在传递参数时使用了值传递?
    这跟我理解的装箱操作有些出入
      

  3.   

    你的理解有所出入。1、
    static void Change(object o)
    {
        o = 5;
    }
    传入的是一个引用的拷贝,你改变拷贝并不能改变引用本身。它跟static void Change(A i){ i.i = 5; }的区别在于:
    虽然A i传入的也是一个引用的拷贝,但这个拷贝和正本都指向了同一个托管对象,修改了拷贝的成员i,等于修改了正本的成员i。
    2、装箱并不是创建一个对象并简单的保存值类型的指针。
    原因很简单,值类型一般生存在堆栈里,堆栈在当前方法完成后就回卷了,
    而作为装箱对象,必须能独立于堆栈存在,比如装箱对象必须从方法中返回后还能使用。因此,记得装箱时候用的是拷贝。
      

  4.   

    -------------------------------
    恩,明白了,o = 5 其实是改变了引用,而并没有改变实例
    这就跟 static void Change(A i)

    i = new A();
    i.i = 5;
     }
    一样,傻掉了
    对于你说的第二点,我的理解是装箱后,栈上的值类型复制了一份拷贝到堆上,object指向的是这个堆上的副本
      

  5.   

    装箱就是隐式的将一个值型转换为引用型对象。
    Change(o);,在栈中创建一个object o,o保存的是堆中存放1的地址。
      

  6.   

    你的理解有所出入。 1、 
    static void Change(object o) 

        o = 5; 

    传入的是一个引用的拷贝,你改变拷贝并不能改变引用本身。 它跟static void Change(A i){ i.i = 5; }的区别在于: 
    虽然A i传入的也是一个引用的拷贝,但这个拷贝和正本都指向了同一个托管对象,修改了拷贝的成员i,等于修改了正本的成员i。 
    2、 装箱并不是创建一个对象并简单的保存值类型的指针。 
    原因很简单,值类型一般生存在堆栈里,堆栈在当前方法完成后就回卷了, 
    而作为装箱对象,必须能独立于堆栈存在,比如装箱对象必须从方法中返回后还能使用。 因此,记得装箱时候用的是拷贝。 
    非常同意。3楼高人