黑马程序员技术交流社区

标题: ref 和out [打印本页]

作者: 殘遛の丶狳味    时间: 2013-8-3 21:45
标题: ref 和out
ref跟out有什么区别  ,什么时候用ref 什么时候用out ???????
作者: 彭家贰小姐    时间: 2013-8-3 22:14
out用于传出值,在方法中必须对out修饰的参数进行赋值

所以

但ref是双向的,即可以传入又可以传出


ref是有进有出,而out是只出不进。

作者: hongiqnglik    时间: 2013-8-3 22:17
ref是在方法外赋值,在方法内改变值,然后带出来,传出来的值是改变后的值。out是多余的返回参数,必须在方法中赋值,然后返回,可以不用再方法外赋值。
作者: sxdxgzr@126.com    时间: 2013-8-4 00:57
本帖最后由 sxdxgzr@126.com 于 2013-8-4 00:58 编辑

1概念:
          ref和out都对函数参数采用引用传递形式:不管是值类型参数还是引用类型参数,并且定义函数和调用函数时都必须显示该参数为ref/out形式。且传递的是实参的地址,类似于C中 的&a(a是变量)。

2两者区别:
         两种参数类型的设计思想不同,ref的目的在于将值类型参数当作引用型参数传递到函数,是函数的输入参数,并且在函数内部的任何改变也都将影响函数外部该参数的值;
而out的目的在于获取函数的返回值,是输出参数,由函数内部计算得到的值再回传到函数外部,因此必须在函数内部对该参数赋值,这将冲掉函数外部的任何赋值,使得函数外部赋值毫无意义。

3表现为:
      a、out必须在函数体内初始化,这使得在外面初始化变得没意义。也就是说,out型的参数在函数体内不能得到外面传进来的初始值。
      b、ref必须在函数体外初始化。
      c、两者在函数体内的任何修改都将影响到函数体外面。
  1. 例:
  2. using System;

  3. namespace ConsoleApplication1
  4. {
  5. class C
  6. {
  7.   public static void reffun(ref string str)
  8.   {
  9.    str += " fun";
  10.   }

  11.   public static void outfun(out string str)
  12.   {
  13.    str = "test";     //必须在函数体内初始, 如无此句,则下句无法执行,报错
  14.    str += " fun";
  15.   }
  16. }

  17. class Class1
  18. {
  19.   [STAThread]
  20.   static void Main(string[] args)
  21.   {
  22.    string test1 = "test";
  23.    string test2;                  //没有初始
  24.    C.reffun( ref test1 );     //正确
  25.    C.reffun( ref test2 );     //错误,没有赋值使用了test2
  26.    C.outfun( out test1 );    //正确,但值test无法传进去
  27.    C.outfun( out test2 );    //正确

  28.    Console.Read();
  29.   }
  30. }
  31. }
复制代码

作者: 黑骏马    时间: 2013-8-4 06:22
本帖最后由 黑骏马 于 2013-8-4 07:16 编辑

下载1.5MB/s,上传却只有7.1KB/s,坑爹啊,狂躁!!!点一次发表花了半个小时时间,还给我发了两次,第一次还是半截内容!!

请无视此楼,或者请管理员删掉吧。

啊,好想砸东西啊!!!
作者: 黑骏马    时间: 2013-8-4 06:41
楼上的回答很详细,简单来说
ref 必须由调用方对参数进行初始化赋值,即ref可以把参数及其值传入被调用方法
out 必须在被调用方内部初始化赋值,即out不接受外部传入的值,像它的名字一样,只出不进

当一个参数有明确的值,需要在被调用方法中进行改变时,用ref
当一个参数没有明确的值,需要通过被调用方法得到值时,用out

写了一个例子:
  1. static void Main(string[] args)
  2. {
  3.     Console.WriteLine("请输入一个数字:");
  4.     int s = Convert.ToInt32(Console.ReadLine());//字符检测代码省略
  5.     int jia;
  6.     bool oushu = Jisuan(ref s,out jia);
  7.     if (oushu)
  8.     {
  9.         Console.WriteLine("输入的{0}是偶数,加{1},新值为{2}",s-jia,jia,s);
  10.     }
  11.     else
  12.     {
  13.         Console.WriteLine("输入的{0}不是偶数,减{1},新值为{2}",s+jia,jia,s);
  14.     }
  15.     Console.ReadKey();
  16. }
  17. /// <summary>
  18. /// 被调用方法
  19. /// </summary>
  20. /// <param name="a">在Main()由用户输入的数字,其值明确,需在被调用方法中改变得到新值</param>
  21. /// <param name="b">b参数值不明确,需要在被调用方法中得到新值,</param>
  22. /// <returns>方法的返回值</returns>
  23. static bool Jisuan(ref int a, out int b)
  24. {
  25.     Random r = new Random();
  26.     b = r.Next(1, 100); //out b 必须在Jisuan()内初始化赋值,外部如果有赋值(int jia=100),则外部赋值无效。
  27.                         //      如果缺少此句,程序会报错,无法运行。
  28.     if (a % 2 == 0)     //ref a 必须在调用方(外部方法)初始化赋值,在Jisuan()内可直接使用
  29.     {
  30.         a += b;
  31.         return true;
  32.     }
  33.     else
  34.     {
  35.         a -= b;
  36.         return false;
  37.     }
  38. }
复制代码


作者: changvh    时间: 2013-8-4 07:34
记住ref和out不能构成重载
作者: 光辉岁月ML    时间: 2013-8-4 09:44
ref 表示参数传递时 按引用传递 就是交换两个数的位置,out表示参数传出 一般方法返回多个值时 使用。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2