zoukankan      html  css  js  c++  java
  • ref和out的区别

    在C#中通过使用方法来获取返回值时,通常只能得到一个返回值。因此,当一个方法需要返回多个值的时候,就需要用到ref和out,那么这两个方法区别在哪儿呢?

    MSDN:
           ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。
          out 关键字会导致参数通过引用来传递。这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化。若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字。 

    案例:

          定义一个方法,求一个整数数组中的最大值,最小值,和,平均数。如果是一个方法只能有一个返回值,那只能每一个都得定义一个方法来实现,不过有了ref和out这实现起来就方便多了。

    ref:

    复制代码
     1    static int GetIntResult(int[] arry, ref float avg, ref int max, ref int min)
     2         {
     3             int sum = 0;
     4             max = arry[0];
     5             min = arry[0];
     6             for (int i = 0; i < arry.Length; i++)
     7             {
     8                 sum += arry[i];
     9                
    10                 if (max < arry[i])
    11                 {
    12                     max = arry[i];
    13                 }
    14                 if (min > arry[i])
    15                 {
    16                     min = arry[i];
    17                 }
    18             }
    19             avg = sum / arry.Length;
    20             return sum;
    21         }
    复制代码

          然后在控制台中试着调用该方法:

    复制代码
    1      static void Main(string[] args)
    2         {
    3             int[] arr = { 1,2,3,4,5,6,7,8,9};
    4             float avg;
    5             int max;
    6             int min;
    7             int sum = GetIntResult(arr, ref avg, ref max, ref min);
    8         }
    复制代码

          此时编译器就会提示画红线,错误:使用了未赋值的avg,max,min

    复制代码
     1       static void Main(string[] args)
     2         {
     3             int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
     4             float avg = 0;
     5             int max = 0;
     6             int min = 0;
     7             int sum = GetIntResult(arr, ref avg, ref max, ref min);
     8             Console.WriteLine("和:{0}	平均值:{1}	最大值:{2}	最小值:{3}", sum, avg, max, min);
     9             Console.Read();
    10         }
    复制代码

    运行结果:

    总结:

          ref这个关键字告诉c#编译器被传递的参数值指向与调用代码中变量相同的内存。这样,如果被调用的方法修改了这些值然后返回的话,调用代码的变量也就被修改了。

          ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中(avg,max,min的初始值为0,调用方法后值改变)。若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。

    out:

          换成out之后,上面的方法不再适用,报错,错误 : 控制离开当前方法之前必须对 out 参数“min”和"max"赋值。你会发现这里max和min在循环外并未初始化。所以才会出错。

    修改后代码:

    复制代码
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace Wolfy.RefAndOut
     8 {
     9     class Program
    10     {
    11         static void Main(string[] args)
    12         {
    13             int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    14             float avg;//在使用out关键字时,不需要在此处初始化,初始化也不会影响到方法内部的值,所以你初始化没用
    15             int max;
    16             int min;
    17             int sum = GetIntResult(arr, out avg, out max, out min);
    18             Console.WriteLine("和:{0}	平均值:{1}	最大值:{2}	最小值:{3}", sum, avg, max, min);
    19             Console.Read();
    20         }
    21         static int GetIntResult(int[] arry, out float avg, out int max, out int min)
    22         {
    23             int sum = 0;
    24             max = arry[0];
    25             min = arry[0];//使用out关键字时,必须在离开方法前对out关键字修饰的参数初始化
    26             for (int i = 0; i < arry.Length; i++)
    27             {
    28                 sum += arry[i];
    29                
    30                 if (max < arry[i])
    31                 {
    32                     max = arry[i];
    33                 }
    34                 if (min > arry[i])
    35                 {
    36                     min = arry[i];
    37                 }
    38             }
    39             avg = sum / arry.Length;
    40             return sum;
    41         }
    42     }
    43 }
    复制代码

         结果和上面一样。

    总结:
           out 关键字会导致参数通过引用来传递。这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化。若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字。

    结论:

           关键字“ref“和”out”之间的唯一区别就是关键字”out“不要求调用代码初始化要传递的参数值。那么关键字‘ref”什么时候用呢?当您需要确保调用方法已经初始化参数值的时候,您就应该使用关键字“ref”。在上面例子中,能够使用“out“是因为被调用的方法并不依赖于被传递的变量的值。个中滋味慢慢体会......

    后话:

          在一论坛里面,偶然看到有这样的帖子,就顺便总结了一下,也算是回忆一下c#基础知识吧。

         想深入了解的可以看这篇文章:http://www.cnblogs.com/dozer/archive/2011/10/28/ref-and-out-keywords.html

    • 博客地址:http://www.cnblogs.com/wolf-sun/ 
      博客版权:如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步! 再次感谢您耐心的读完本篇文章。
    文章出处:http://www.cnblogs.com/wolf-sun/p/3371174.html
  • 相关阅读:
    java编译错误No enclosing instance of type TestFrame is accessible. Must qualify the allocation with an enclosing instance of type TestFrame (e.g. x.new A(
    java 2中创建线程方法
    动态规划基本思想
    关于eclipse编译一个工程多个main函数
    java Gui初识
    Eclipse中java项目的打包
    java 播放声音
    把资源文件夹导入到eclipse中
    Java建立JProgressBar
    How to grant permissions to a custom assembly that is referenced in a report in Reporting Services
  • 原文地址:https://www.cnblogs.com/net-sky/p/10021499.html
Copyright © 2011-2022 走看看