下面这段代码输出什么结果?为什么这样输出?[b]using System;[/b]
大家看看吧............
using System.Collections.Generic;
using System.Text;namespace ConsoleApplication1
{
    class Value
    {
        public int i = 15;
    }
    class Program
    {
        static void Main(string[] args)
        {
            Program t = new Program();
            t.first();
        }
        public void first()
        {
            int i = 5;
            Value v = new Value();
            v.i = 25;
            second(v, i);
            Console.WriteLine(v.i);
        }
        public void second(Value v, int i)
        {
            i = 0;
            v.i = 20;
            Value val = new Value();
            v = val;
            Console.WriteLine(v.i+" "+i+" ");
        }
    }
}

解决方案 »

  1.   

    using System.Collections.Generic; 
    using System.Text;
    using System;namespace ConsoleApplication1
    {
        class Value
        {
            public int i = 15;
        }
        class Program
        {
            static void Main(string[] args)
            {
                Program t = new Program();
                t.first();
            }
            public void first()
            {
                int i = 5;
                Value v = new Value();
                v.i = 25;
                second(v, i);
                Console.WriteLine(v.i);//20 ?????看不懂 郁闷的问题
            }
            public void second(Value v, int i)
            {
                i = 0;
                v.i = 20;
                Value val = new Value();
                v = val;
                Console.WriteLine(v.i + " " + i + " ");//15,0 可以理解
            }
        }
    }
      

  2.   


    没看到引用呢!!!! 不是ref吗!! 请讲讲 !我也奇怪
      

  3.   

    关键在于方法second中, v=val; 这句话是对象引用指向了新的Value类实例.
    在方法first中, 实例v的值在second中已经被改变.简单的话, 类是引用类型, 所以是地址传递
      

  4.   


    using System.Collections.Generic; 
    using System.Text;
    using System;namespace ConsoleApplication1
    {
        class Value
        {
            public int i = 15;
        }
        class Program
        {
            static void Main(string[] args)
            {
                Program t = new Program();
                t.first();
            }
            public void first()
            {
                int i = 5;
                Value v = new Value();
                v.i = 25;
                second(v, i);
                Console.WriteLine(v.i);//20 ?????看不懂 郁闷的问题
                                            //因为在second里,v.i的值被赋为20
                                       //之后再second中,v=val;v的引用变成了val,但是此方法中的v还是原来的那个
            }
            public void second(Value v, int i)
            {
                i = 0;
                v.i = 20;
                Value val = new Value();
                v = val;
                Console.WriteLine(v.i + " " + i + " ");//15,0 可以理解
            }
        }
    }
      

  5.   

    大致是这样吧,刚学几天,不太懂using System.Collections.Generic; 
    using System.Text;
    using System;namespace ConsoleApplication1
    {
        class Value
        {
            public int i = 15;
        }
        class Program
        {
            static void Main(string[] args)
            {
                Program t = new Program();
                t.first();
            }
            public void first()
            {
                int i = 5;
                Value v = new Value(); 此时v.i=15,i=5
                v.i = 25; 此时v.i=25
                second(v, i); 另起一个副本,不影响此v实例
                Console.WriteLine(v.i);//20 
            }
            public void second(Value v, int i)
            {
                i = 0; 此时v.i=25
                v.i = 20; 
                Value val = new Value(); 
                v = val;到此处是一个全新的value实例,val.i=v.i=15
                Console.WriteLine(v.i + " " + i + " ");//15,0 可以理解
            }
        }
    }
      

  6.   

    输出 : 15 0 
           20 Main方法中已经写的很清楚了 执行first()   
    其中 second(v,i)  返回结果输出  15 0 
     而 frist()方法中Console.WriteLine(v.i) 的v.i 已经是 second() 中定义的v.i。
      

  7.   

    不使用ref   
      传的是引用,可以对引用的对象进行操作   
      比如,传一个人进来,你可以打他一顿,可以请他喝酒,但只能是对这个特定的人人操作   
        
      使用ref,传的是引用的引用,可以改变这个引用,指向别的引用   
      使用ref传一个人进来,相当于一个人所在的位置,你可以把这个人赶走,换成另外一个人
    在这里我要谢谢楼主,没有楼主我也不可能知道,难怪我前些天提关于Array的某些方法的时候,没看到ref关键字!!
    原来是这样
      

  8.   

    15 0
    20 这个是引用的问题 没有ref 等 second v还是原来的哪个 但你可以修改v里的内容.不能改变对V的引用..,
      

  9.   

    同意.没有改变v的引用  public  class Value
            {
                public int i = 15;
            } 
            static void Main(string[] args)
            {
                Program t = new Program();
                t.first();
            }
            public void first()
            {
                int i = 5;
                Value v = new Value();
                v.i = 25;
                second(ref v, i);
                Console.WriteLine(v.i);
            }
            public void second(ref Value v, int i)
            {
                i = 0;
                v.i = 20;
                Value val = new Value();
                v = val;
                Console.WriteLine(v.i + " " + i + " ");
            } 改成上面这样对比一下就好理解了,单步调试下
      

  10.   

    晕死 各位老大 看清楚题
    正确答案是这样:(楼主要给分的)
     发表于:2009-03-06 16:21:1410楼 得分:0 
    大致是这样吧,刚学几天,不太懂 C# code
    using System.Collections.Generic; 
    using System.Text;
    using System;namespace ConsoleApplication1
    {
        class Value
        {
            public int i = 15;
        }
        class Program
        {
            static void Main(string[] args)
            {
                Program t = new Program();
                t.first();
            }
            public void first()
            {
                int i = 5;
                Value v = new Value(); 此时v.i=15,i=5
                v.i = 25; 此时v.i=25是正确的
                second(v, i); 另起一个副本,不影响此v实例
                Console.WriteLine(v.i);//20 
            }
            public void second(Value v, int i)
            {
                i = 0;  没看到下面?
                v.i = 20; 此时v.1被设置成20了 还没有副本
                Value val = new Value();//这里下面这里才是副本才跟first方法里的对象v无关 
                v = val;//val.i=v.i=15
                Console.WriteLine(v.i + " " + i + " ");//15,0 
            }
        }

     
      

  11.   

    简单来说,first里面v是一个引用类型,其指向一个地址,然后second里面的v又是另一个引用类型,是一个全新的地址了
    两个v不同的东西指向当然不同不要搞混
      

  12.   

    然而second里面传入的参数v还是first里面的指向地址
      

  13.   


    Value是一个类,类是引用类型。 
      

  14.   

     public  class Value
            {
                public int i = 15;
            } 
            static void Main(string[] args)
            {
                Program t = new Program();
                t.first();
            }
            public void first()
            {
                int i = 5;
                Value v = new Value();
                v.i = 25;
                second(ref v, i);
                Console.WriteLine(v.i);
            }
            public void second(ref Value v, int i)
            {
                i = 0;
                v.i = 20;
                Value val = new Value();
                v = val;请问这里v指向了新的内存以后,为什么first方法中的最后一句仍然使用原来的V的地址?
                Console.WriteLine(v.i + " " + i + " ");
            } 
      

  15.   

      Value val = new Value();   是一个新的对象,所以他的赋值与前面传过来的值无关了,他的值更改,是不会影响方法传递的参数的!
      

  16.   

    namespace ConsoleApplication1 

        class Value 
        { 
            public int i = 15; 
        } 
        class Program 
        { 
            static void Main(string[] args) 
            { 
                Program t = new Program(); 
                t.first(); 
            } 
            public void first() 
            { 
                int i = 5; 
                Value v = new Value(); 
                v.i = 25; 
    //由于v对象是class类型(.net中的引用类型),
    //所以下面在进行参数传递时实际传递的是Value对象的一个引用v;
    //其实相当于传递C++中对象的指针;
                second(v, i); 
                Console.WriteLine(v.i); 
            } 
            public void second(Value v, int i) 
            { 
                i = 0; 
    //此处是对v所引用的对象的属性进行赋值;
    //相当于C++中v指针所指向的对象的属性赋值;
                v.i = 20; 
                Value val = new Value(); 
                v = val; 
    //此处将v和val引用同一个对象(上面新创建出的)
    //相当于C++中v指针指向了val指针所指的对象;
                Console.WriteLine(v.i+" "+i+" "); 
            } 
        } 
      

  17.   

     public void second(ref Value v, int i) 
            { 
                i = 0; 
                v.i = 20; 
                Value val = new Value(); 
                v = val;请问这里v指向了新的内存以后,为什么first方法中的最后一句仍然使用原来的V的地址?,
                        这是个局部变量,用完后就释放了吧.. 
                Console.WriteLine(v.i + " " + i + " "); 
            } 
      

  18.   

    说白了就是一个new的问题,用ref更清楚些
      

  19.   

    这问题是程序员经常的错误没有ref 那么我们就是值传递,这没有什么好说的,打死都无法改变这个对象的指针。那么对象内部的值为什么能改呢?原因很简单,因为对象本身而言是引用类型,因此在任何地方改变其内部都是可行的。了解一下封装的概念。
      

  20.   


    不是局部变量的问题,改成下面的程序结果也是一样,说到底就是个值传递<引用传递> 值类型<引用类型> 的区别。
    namespace ConsoleApplication1
    { class Value
    {
    public int i = 15;
    }
    class Program
    {
            Value val2 = new Value(); static void Main(string[] args)
    {
    Program t = new Program();
    t.first();
    }
    public void first()
    {
    int i = 5;
    Value v = new Value();
    v.i = 25;
    second(v, i);
    Console.WriteLine(v.i);
    }
    public void second(Value v, int i)
    {
    i = 0;
    v.i = 20;
    v = val2;
    Console.WriteLine(v.i + " " + i + " ");
    }
    }
      

  21.   

    value是类是引用类型,对它的改动会反映在内存托管堆上,而i是值类型,在参数传递时候传送出去的只是它的一个副本,不会改变原始值在栈中的值,LZ补下基础吧
      

  22.   

    谁说v = val;之后first方法中的最后一句仍然使用原来的V的地址?
    这里的方法签名已经修改成了public void second(ref Value v, int i)
    有个“ref”关键字在,所以:
    v = val;语句之后v已经变为新对象的引用了。
    单步调试一下就清楚了。
      

  23.   

        class Value 
        { 
            public int i = 15; 
        } 
        class Program 
        { 
            static void Main(string[] args) 
            { 
                Program t = new Program(); 
                t.first(); 
            } 
            public void first() 
            { 
                int i = 5; 
                Value v = new Value(); 
                v.i = 25; 
                second(v, i); //此处v对象传递给方法的是引用地址,所以second中v.i=20 就修改了托管堆中的数据 所以此处v.i = 20
                Console.WriteLine(v.i); 
            } 
            public void second(Value v, int i) 
            { 
                //此处的v是原始v引用地址的一个副本 但引用还是指向托管堆中的对象,所以此处v.i=20修改了原对象v.i的值
                i = 0; 
                v.i = 20; 
                Value val = new Value(); 
                v = val; //这里创建了VALUE的新实例并分配了行的引用地址,对把引用地址传给了次方法中的v(这个原对象v引用地址的一个副本),所以v的引用指向新创建的val对象,即:v.i = 15
                Console.WriteLine(v.i+" "+i+" "); 
            } 
        } 
      

  24.   

    这道题的关键,就是传进方法的参数只是复制一份引用地址,然后将这个新复制的地址赋给Value v这个局部变量而已
      

  25.   

    改了下send方法的参数名v为t,这样可能更好看些:
    using System.Collections.Generic; 
    using System.Text; namespace ConsoleApplication1 

        class Value 
        { 
            public int i = 15; 
        } 
        class Program 
        { 
            static void Main(string[] args) 
            { 
                Program t = new Program(); 
                t.first(); 
            } 
            public void first() 
            { 
                int i = 5; 
                Value v = new Value(); 
                v.i = 25; 
                second(v, i); 
                Console.WriteLine(v.i); 
            } 
            public void second(Value t, int i) //改了下参数v为t
            { 
                i = 0; 
                t.i = 20; 
                Value val = new Value(); 
                t = val; //此处t被指向了val的地址,和原先的v断开了联系
                Console.WriteLine(t.i+" "+i+" "); 
            } 
        } 
    }
    再说个相似的例子:
    int[] a = new int[] { 1, 2, 3 };
    int[] b = new int[] { 7, 8, 9 };int[] c = a;
    c[1] = 200;//改变了a[1]的值
    c = b;//c指向了b,和a没关系了Console.WriteLine(c[1].ToString());
      

  26.   

    15 0
    20如果楼主看过 你必须知道的.NET 就明白了ref 引用类型 是改变引用类型的地址 也就是指针
    没有ref 就是没改变而 value对象的内部值(好比给v开辟的一个内存块的里的i的值变了)修改了v的内部 并没有修改v
      

  27.   

    其实我感觉  更像是糊弄人的题目
    只要里面有两个V拿来弄晕人的,感觉这题其实是脑筋急转弯.看上面强人的解释还不明白的看这里.    class Value
        {
            public int i = 15;
        }
        class Program
        {
            static void Main(string[] args)
            {
                Program t = new Program();
                t.first();
                Console.Read();
            }
            public void first()
            {
                int i = 5;
                Value v = new Value();
                v.i = 25;
                second(v, i);
                Console.WriteLine(v.i);
            }
            public void second(Value v, int i)
            {
                i = 0;
                v.i = 20;//这里的V其实是first()里面的Value v = new Value();实例化后的.改变后first()输出的当然v.i是20.
                Value val = new Value();
                v = val; //这里的V是second(Value v, int i)里的V,新的Value val = new Value();实例化.V =VAL后,V.I等于15是理所当然的.
                Console.WriteLine(v.i + " " + i + " ");
            }
        }
      

  28.   

    永远的门槛,经典的混乱   终于看明白了
      public void first() 
            { 
                int i = 5; 
                Value v = new Value(); 
                v.i = 25; 
                second(v, i); 
                Console.WriteLine(v.i); 
            } 
            public void second(Value t, int i) //改了下参数v为t
            { 
                i = 0; 
                t.i = 20; 
                Value val = new Value(); 
                t = val; 
                 Console.WriteLine(t.i+" "+i+" "); 
            } 
    second 里面可以对参数t 内部的东西做改变,但是改变不了t本身的引用,也就是说first 函数里面的v去second 里面去转了一下,本身的性质可能改变但是本身的引用没有改变 性质也就是v.i变成了20 .sccond 里面的t引用 的是val的值
      

  29.   

    15 0
    20引用和值传递:
    Value的构造函数用引用传递类的对象实验证明也事如此(上机试过了)
    :)
      

  30.   

    15 0
    20
    这道题不是很难啊!
    LZ应该对C#中的两个数据类型——值类型和引用类型再熟悉熟悉!
      

  31.   

    原因就是在c#中传递的引用其实是对象的地址的拷贝。所以Second(v,i)中的v是Main中v的地址的拷贝,所以在Second中使用v.i就是把v指向的引用的i值修改,就可以修改Main中v的值,但是v = new Value()其实是将一个新的地址赋值给v,因为v本来就是个地址的拷贝所以不会影响Main中v的引用地址。所以v.i就是20.
      

  32.   

    这个就是关键了.说白了,引用类型,传递的引用,也不是引用自身,而是引用的一个copy
    比如Main中的v,指向实例,暂时叫做x实例.
    传入second的v,其实是v的一个引用copy,不过这个v copy也是指向的x实例,所以你修改v copy的值,其实就是修改了x实例的值,Main中的v,是指向x实例的,所以v实例的值也变了
    但是v自身,是个引用,所以当second中的v=val后,只是v copy指向val了,Main中的v还是指向的x实例
      

  33.   

    上面说错了..不是Main中的v,是First()中的v...
      

  34.   

    15 0
    20
    把public void second(ref Value v, int i)
            {
                i = 0;
                v.i = 20;
                Value val = new Value();
                v = val;
                Console.WriteLine(v.i + " " + i + " ");
            } 
    中的Value val = new Value();
                v = val;
    去掉得到为
    20 0
    20
    这样就比较容易理解了
      

  35.   

    我看了一下  觉得 输出结果因该是
    15  0 
    15
    引用数据类型 在方法里面进行值传递时都会保留在方法里面的值修改
    public void first()
            {
                int i = 5;
                Value v = new Value();
                v.i = 25;
                second(v, i); //这里面时候v的最后被val 这个实列赋值了             Console.WriteLine(v.i);//v.i也就是val.i 所以 =15
            }
            public void second(Value v, int i)
            {
                i = 0;
                v.i = 20;
                Value val = new Value();
                v = val; //此时v我指像 val这个地址的 
                Console.WriteLine(v.i + " " + i + " ");//15,0 可以理解
            }
      

  36.   

    类是个应用类型,把类当成参数实际就是一个ref传参
      

  37.   

    我用vb写程序,看了lz的这段代码,更是弄不清楚了。建一个控制台程序。代码如下:
    Module Module1    Class Value
            Public i As Integer = 15
        End Class    Public Sub Main(ByVal args As String())
            Call first()
        End Sub    Public Sub first()
            Dim i As Integer = 5
            Dim v As New Value()
            v.i = 25
            second(v, i)
            Console.WriteLine(v.i)        '15
            Console.ReadLine()
        End Sub    Public Sub second(ByRef v As Value, ByRef i As Integer)
            i = 0
            v.i = 20
            Dim val As New Value()
            v = val
            Console.WriteLine(v.i & " " & i & " ")        '15 0
        End Sub
        
    End ModuleModule Module1    Class Value
            Public i As Integer = 15
        End Class    Public Sub Main(ByVal args As String())
            Call first()
        End Sub    Public Sub first()
            Dim i As Integer = 5
            Dim v As New Value()
            v.i = 25
            second(v, i)
            Console.WriteLine(v.i)        '20 
            Console.ReadLine()
        End Sub    Public Sub second(ByVal v As Value, ByVal i As Integer)
            i = 0
            v.i = 20
            Dim val As New Value()
            v = val
            Console.WriteLine(v.i & " " & i & " ")        '15 0
        End Sub
        
    End Module看看上面两段代码,谁给解释解释?
      

  38.   

    就这两句有区别Public Sub second(ByRef v As Value, ByRef i As Integer)
    Public Sub second(ByVal v As Value, ByVal i As Integer)