class Program
    {
        private string a;        private int b;        static void Main(string[] args)
        {
            Program p1 = new Program();
            p1.a = "p1a";
            p1.b = 1;
            Program p2 = new Program();
            p2.a = "p2a";
            p2.b = 2;
            new Program().ChangeA(p1, p2);
            Console.WriteLine(p1.a + p1.b);            new Program().ChangeB(p1, p2);
            Console.WriteLine(p1.a + p1.b);           
        }        private void ChangeA(Program p1, Program p2)
        {
            p1 = p2;
        }        private void ChangeB(Program p1, Program p2)
        {
            p1.a = p2.a;
            p1.b = p2.b;
        }
无论参数是基本类型还是值类型,都不会改变原来的值,这是为什么?
调用ChangeB方法又可以改变对象中属性的值,这又是为什么?

解决方案 »

  1.   

    new Program().ChangeA(p1, p2);
    创建了一个新的实例,而不是在原来的实例上运行的
      

  2.   

    问过无数次的问题...在C#中,未经ref或out关键字声明,任何参数都是“按值传递”与参数类型无关...去看MSDN...
      

  3.   

    new Program().ChangeB(p1, p2);
    只是一个进行数据交换的方法而已
      

  4.   

    第一点明白了!
    那么第二个方法
    ChangeB(p1, p2);这个为什么可以改变?
      

  5.   

    传入的参数为引用类型时,可以改变;值类型需要用到ref out。
      

  6.   

    如果传入的是引用类型,内部的属性是可以改变的,但引用对象本身无法改变。如果传入的是值类型,对象本身及内部属性都无法改变,常见的比如结构体。
    如果使用ref关键字,则无论是引用类型还是值类型,其内部属性及对象本身都可以改变。
      

  7.   

    当然不会改变...这个问题反复出现还总是有人搞不清楚基本上就是指针害的,在.NET中一定要忘记C/C++的指针!.NET中的引用和C/C++指针虽然相似但却是完全不同的概念,.NET中的引用是远比指针更复杂的结构...
    多看看MSDN...
    传递参数(C# 编程指南)
      

  8.   

    ref其实用的不多,一般使用类,对属性赋值传递即可,因为ref的参数无法全局保持,只能出现在函数中。不过替代方案是用static静态变量,静态的变量性质等同于ref传递,无论是值类型还是引用类型。
      

  9.   

    按这个可以解释这两个方法:
    这两个方法都是"按值传递",同时也是"传递引用类型参数",所以p1=p2无效,不能改变P1的指针。
    但p1.a = p2.a;有效,没改变指针,但可以改变其中的属性,改变的是P1指针空间中的属性值。
      

  10.   

    private void ChangeA(ref Program p1,ref Program p2)
            {
                p1 = p2;
            }        private void ChangeB(ref Program p1,ref Program p2)
            {
                p1.a = p2.a;
                p1.b = p2.b;
            }