方法参数ref,out的问题!(params先不说)对于值型变量作为方法参数时,可以有三种情况:
1.没有ref和out参数  (直接传值,不能改变实参)
2.使用ref参数       (引用传递,输入,可以改变实参)
3.使用out参数       (引用传递,输出,可以改变实参)我不明白的是,对于引用类型的变量的三种情况:
1.没有ref和out参数  (引用传递,可以改变实参)
2.使用ref参数       (引用传递,输入) ?
3.使用out参数       (引用传递,输出) ?引用类型的变量使用时传递的就是"引用",即好比C中的指针.
那么再加参数ref和out时,不是传递"引用的引用"了吗?而且若是输入参数,引用类型变量加上ref和不加ref不都是能
改变实参的值吗,难道仅为区别输入输出而加out?我有点糊涂,虽然写代码可以完成工作,但找不到明确说明它们
之间关系和使用情况的官方资料(MSDN),有谁可以告诉我一下?

解决方案 »

  1.   

    它用于值类型啊,还有ref和out的区别在于一个需要初始化,另一个不需要...而本来就是引用类型的对象不需要这两个关键字撒..应该
      

  2.   

    对于值类型,加上ref和out参数就相当于是引用变量的别名。
    对于引用类型,一般不用加ref和out参数,本身的意思就是引用对象的别名
      

  3.   

    看个实例吧
    n=0调用函数之前。
    public  int  zongshu( TreeNodeCollection   nodes ,int n )   ///遍历结点,选择checkbox选中的结点的总数
    {  
    foreach(TreeNode   node   in   nodes)   
    {   
    if(node.Checked==true)
    {
    n=n+1;
    }
    zongshu( node.Nodes ,n);   

              MessageBox.Show("nzhi"+n,"注意12");
    return n;
    }
    如果n前面不加ref,则每次调用都从0开始记数,最后当然结果不对,然而加上之后就能得到总的结点数,就象这样zongshu( node.Nodes ,ref n);   zongshu( TreeNodeCollection   nodes ,ref int n ) ,但在实参中定义为int n就可以,引用时也要加上ref,就是这样,比如要传的是a=0,zongshu( node.Nodes ,ref a);   这样就可以了。
      

  4.   

    根输入,输出有关系吗?既然是引用改变那么就会对原来的值例如:int s; 或 int k=0;进行传它们的引用撒:
    class TestRO
    {
     // ...
     void TestRef(ref int i)
     {
        i+=2;
     }
     void TestOut(out int i)
     {
       s+=3;
     }
     // ...
    }
    static void Main(string args[])
    {
      int s,k=0;
      s=20;
      k=30;
      TestRO tro=new TestRO();
      tro.TestRef(ref k);
      tro.TestOut(out s);
      Console.WriteLine("test ref : {0}",  k);
      Console.WriteLine("test out : {0}",  s);
      Console.ReadLine();  
    }//执行结果应该是: 
    test ref : 22
    test out : 33
      

  5.   

    1)out和ref只针对值类型,对类来讲,本身就传引用过去,因此不需要这两个关键字。
    2)ref 和out的区别在于,out不需要初始化参数。
      

  6.   

    上面写错了一些,应该是23,32,而且TestOut方法形参不一致,写慌了,改成一至的就行了"i"
      

  7.   

    ref 传参要求参数已经是事例化,这在有的调用有安全的保证
      

  8.   

    to :ProjectDD
    存在肯定有用.对于类对象等引用类型,若是要方法返回一个对象在方法参数中,
    不是要用到out参数吗?to : rola
    我碰到过会循环调用"引用",所以才要搞清楚,to :diandian82
    1.没有ref和out参数  (引用传递,可以改变实参)
    2.使用ref参数       (引用传递,输入,可以改变实参)to :keikeiandlili
    是的to :ProjectDD
    方法定义体不对吧,找不到局部变量s.
    void TestOut(out int i)
     {
       s+=3;
     }to : kssys() 
    说的不错,不过在MSDN中我没有找到关于这个的明确语法说明.
    另外,若是要方法返回一个对象在方法参数中,
    不是要用到out参数吗? 比如: a(out string s,...)
      

  9.   

    对于值型变量作为方法参数时,可以有三种情况:
    1.没有ref和out参数  (直接传值,不能改变实参)
    2.使用ref参数       (引用传递,输入,可以改变实参)
    3.使用out参数       (引用传递,输出,可以改变实参)我不明白的是,对于引用类型的变量的三种情况:
    1.没有ref和out参数  (引用传递,可以改变实参)
    2.使用ref参数       (引用传递,输入) ?
    3.使用out参数       (引用传递,输出) ?没有深入研究过
    一般如果是ref out 接口(引用类型)应该是对引用的引用。
    调试通过就没管了。
    一下
      

  10.   

    引用类型变量加上ref和不加ref不都是能改变实参的值吗用ref 通常都是用作返回參數時使用的吧,一般輸入參數沒有必要用ref
      

  11.   

    昨晚又细想了一下,理了理,发现还是kssys说的有条理.首先是:
    (1)out和ref只针对值类型,对类来讲,本身就传引用过去,因此不需要这两个关键字。
    (2)ref 和out的区别在于,out不需要初始化参数。然后是(3)引用类型的变量使用ref和out参数,
    即是引用的引用还是仍然是单一引用?不过结果都一样的.
      

  12.   

    by value 和by ref不管他们对什么类型都有着本质的区别.by value在传递的时候传递的是该值的一个拷贝,不管它是值类型还是引用类型.
    所以在传递一个值类型的时候,返回的时候不会变,但是为什么引用类型会变呢?因为这时候传送的是引用类型的拷贝地址,只不过自己的地址和传送的地址指向同一个堆.
    在被调用的函数里面改变了值,即改变了堆的值,而自己的地址也指向这个堆,所以他会变.by ref在传递的时候传递的是他自己,传递和被传递根本就是一个东西,所以会变.我觉得这个是最本质的区别,正是因为这个区别,所以by value 和by ref的行为不一样.但是有一个特殊,string类型,他是引用类型,但却表现出值类型的行为,就是说在被调用函数里面改变string的值,但是他返回的时候不会改变.
    (1)out和ref只针对值类型,对类来讲,本身就传引用过去,因此不需要这两个关键字
    ------------------------------
    我觉得这个是不对的.
    不要认为,引用类型加和不加by ref是一样的.如果你想做实验,也不要直接传个类,然后一个加ref,一个不加ref,因为这样表面的行为是一样的,看不出来.如果你在被调用函数里面把传过来的类=null,你就可以看出区别了,加ref的会抱空引用(清空的和原来的是一个东西),不加的不会抱错(清空的和原来的是两个东西).
      

  13.   

    呵呵。
    TO:(1)out和ref只针对值类型,对类来讲,本身就传引用过去,因此不需要这两个关键字
    ------------------------------
    我觉得这个是不对的.
    不要认为,引用类型加和不加by ref是一样的.类加上ref或out,只会让你回到原始的C++的指针时代,违反了C++->C#的进化论,因此尽量不用,所以可以忽略它。
      

  14.   

    同意kssys.但就找不能官方的明确的这主面的说明资料,有谁知道?
      

  15.   

    MSDN里面就有out和ref的官方资料啊。
      

  16.   

    public class A
    {
        public int temp;
        public string str;
    }
    存在对象 A obj; A obj21.没有ref和out参数  (引用传递,可以改变实参) 
       fun(obj)  ---->函数内可以改变obj中temp和str,但obj指向的对象在函数返回后始终不变2.使用ref参数       (引用传递,输入) ?
      fun(ref obj)--->函数内部可以让obj=obj2  函数返回后obj obj2 将指向同一个对象;3.使用out参数       (引用传递,输出) ?
    fun(out obj) ---->当前obj指向的对象将被替换为函数内指向的对象。
      

  17.   

    我已经解释了,刚学习的人如果认为    引用类型加和不加by ref是一样的,应该只有害处, 我始终认为 引用类型加和不加by ref也有本质的区别.例子我也举了,如果你想做实验,也不要直接传个类,然后一个加ref,一个不加ref,因为这样表面的行为是一样的,看不出来.如果你在被调用函数里面把传过来的类=null,你就可以看出区别了,加ref的会抱空引用(清空的和原来的是一个东西),不加的不会抱错(清空的和原来的是两个东西).
      

  18.   

    okkk,的例子很有说明性,我试试.to kssys() :MSDN 中的资料说得不深
      

  19.   

    using System;
    using System.Collections.Generic;
    using System.Text;namespace TestRef
    {
        class Program
        {
            static void TestRef(ref int i){i+=5;}
            static void Test(int i){i+=5;}
            static void Main(string[] args)
            {
                int i1, i2;
                i1 = 10;
                i2 = 10;
                TestRef(ref i1);//
                Test(i2);//
                Console.WriteLine("i1={0}, i2={1}", i1, i2);
                Console.ReadLine();
            }
        }
    }
    结果:i1=15, i2=10
    分析
    如果不用ref那么方法Test对实参i2的改变(i2=i2+5)到那里去了?合理的解释是,传的是一个考贝.
      

  20.   

    为了证明其传的是一个复制本,那么设计一个新测试如下:
    using System;
    using System.Collections.Generic;
    using System.Text;namespace TestRef
    {
        class Program
        {
            static void TestRef(ref int i)
            {
                i += 5;
            }
            static void Test(int i)
            {
                Console.WriteLine("Test中的实参为: {0}", i);
                i += 5;
                Console.WriteLine("Test中的实参为修改后为: {0}", i);
            }
            static void Main(string[] args)
            {
                int i1, i2;
                i1 = 10;
                i2 = 10;
                TestRef(ref i1);//
                Test(i2);//
                Console.WriteLine("i1={0}, i2={1}", i1, i2);
                Console.ReadLine();
            }
        }
    }
    结果:
    Test中的实参为: 10
    Test中的实参为修改后为: 15
    i1=15, i2=10这充分说明了,再传递实参(区别于函数定义时称为"形式参数"的称法)时是传递实参的一个复制本这个复制本与实参值相等,但处于内存中不同的位置,换言之如果单独对其中任何一个进行修改,那么这种修改的影响只会对其本身产生影响而与其它任何内在位置的其自身的复制本无关!