在C#中把一个参数设置为out类型,难道只是
为了在函数中改变他的值,用来给后面的代码使用?
这和在函数外设置一个变量,然后在函数里改变它的值,
有什么不同?
请高手指点一下!谢谢!!!

解决方案 »

  1.   

    The out keyword causes arguments to be passed by reference. This is similar to the ref keyword, except that ref requires that the variable be initialized before being passed. 
    out 和 ref 的区别就是传入的参数是否已经初始化了.class OutExample
    {
        static void Method(out int i)
        {
            i = 44;
        }
        static void Main()
        {
            int value;
            Method(out value);
            // value is now 44
        }
    }class OutExample
    {
        static int i ;
        static void Method(int i)
        {
            i = 44;
        }
        static void Main()
        {
            
            Method(i);
            // value is now 44
        }
    }这两种实现的效果都是一样的,不过定义成成员变量后,首先是资源的浪费吧
      

  2.   

    意思差不多 但是有的变量的值是不会改变的 所以只能用out
      

  3.   

    c#的变量声明 和使用 必须是 例如:int a =5; 这样a才可以被使用
    如果是:int b ; b除非被赋值,否则使用他的地方有一个编译时的错误。
    out 相对于ref ,out修饰的参数,可以像b一样,不用被赋值,而直接代到方法的参数中去,但在方法中,带有out修饰符的,必须首先被赋值。ref,要想a一样,必须 先被赋值才能代到方法的参数中去,要不然,有一个编译时的错误。
    out同ref一样,都是有一级地址传递的,也就是,带有这两个修饰符的参数,如果被修改了原来的值,将以新的值作为他的值,
      

  4.   

    话说古时候,在一个名字叫C#的繁华的大城市里面,有两家珠宝加工店,一家叫ref,另外一家叫out。有一天,有名字叫a和b的两个人每人都各带了一公斤黄金要加工首饰。a去了ref店,ref的掌柜告诉a说,请客官稍等,我们加工的速度是很快的,大概就一个小时左右吧。a说,我敢时间呢,能不能用我的黄金换现成的首饰。ref老板说,客官,实在是对不起,本店只为客人加工,我们没有这样的服务。如果您敢时间的话,我推荐您去out店,他们专门做这样的业务。b去了out店,说,掌柜的,你必须要用我的这一公斤黄金给我加工首饰。out店的掌柜不好意思的笑了笑,客官实在是对不起我们这里只用黄金交换加工好了的首饰。我们不提供加工的服务,你可以去ref店,他们专门做这样的业务。就这样,两家店各做各的,都说同行是冤家。两个店却关系很好。业务都蒸蒸向上。两家店都相安无事的过了很多年。突然城东开了一家名叫params的店。这家什么都加工,不管是黄金珠宝还是黑土白云。不过由于不太专业,光顾的客人不怎么多。(故事而已,如有雷同。纯属娱乐。)
    示例代码:1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;

    6 namespace RefDifferenceToOut
    7 {
    8     class Program
    9      {
    10         static void Main(string[] args)
    11          {
    12             //这里做为ref类型的参数必须初始化。ref类型参数传入未初始化变量会报错。
    13             string refTestStr = string.Empty;
    14 
    15             //作为out类型参数可以不初始化,因为out类型参数是在函数内部赋值。
    16             string outTestStr = string.Empty;
    17             
    18              Program p = new Program();
    19            
    20              Console.WriteLine("默认空值输出:");
    21              Console.WriteLine(p.UseRef(ref refTestStr));
    22              Console.WriteLine(p.UseOut(out outTestStr));
    23              Console.WriteLine("refTestStr:" + refTestStr);
    24              Console.WriteLine("outTestStr:" + outTestStr);
    25              Console.WriteLine("-------------------");
    26 
    27              refTestStr = "1";
    28              outTestStr = "2";
    29 
    30              Console.WriteLine("从新赋值:refTestStr = \"1\";outTestStr = \"2\";");
    31              Console.WriteLine(p.UseRef(ref refTestStr));
    32              Console.WriteLine(p.UseOut(out outTestStr));
    33              Console.WriteLine("refTestStr:" + refTestStr);
    34              Console.WriteLine("outTestStr:" + outTestStr);
    35              Console.WriteLine("-------------------");
    36 
    37 
    38              refTestStr = "3";
    39              outTestStr = "4";
    40              Console.WriteLine("从新赋值:refTestStr = \"3\";outTestStr = \"4\";");
    41              Console.WriteLine(p.UseRef(ref refTestStr));
    42              Console.WriteLine(p.UseOut(out outTestStr));
    43              Console.WriteLine("refTestStr:" + refTestStr);
    44              Console.WriteLine("outTestStr:" + outTestStr);
    45              Console.WriteLine("-------------------");
    46 
    47 
    48              Console.WriteLine("--------params-------");
    49              p.param("str_a", "2", "3", "4");
    50 
    51 
    52          }
    53 
    54         public string UseRef(ref string refTest)
    55          {
    56             return refTest += "rrrrrref";
    57          }
    58 
    59         public string UseOut(out string outTestStr)
    60          {
    61             //在这里需要给outTest从新赋值
    62              outTestStr = "0";
    63              outTestStr += "oooooout";
    64             return outTestStr;
    65          }
    66 
    67         /// <summary>
    68         /// params参数练习。
    69         /// </summary>
    70         /// <param name="a">同是string参数</param>
    71         /// <param name="list">string 类型列表参数</param>
    72         public void param(string a,params string[] list)
    73          {
    74              Console.WriteLine(list.ToString());
    75 
    76             int i = 0;
    77 
    78              Console.WriteLine(a);
    79             foreach (string s in list)
    80              {
    81                  Console.WriteLine(i++ +"_"+ s);
    82              }
    83          }
    84      }
    85 }
    86 
    输出结果:默认空值输出:rrrrrref0ooooooutrefTestStr:rrrrrrefoutTestStr:0oooooout-------------------从新赋值:refTestStr = "1";outTestStr = "2";1rrrrrref0ooooooutrefTestStr:1rrrrrrefoutTestStr:0oooooout-------------------从新赋值:refTestStr = "3";outTestStr = "4";3rrrrrref0ooooooutrefTestStr:3rrrrrrefoutTestStr:0oooooout---------------------------params-------System.String[]str_a0_21_32_4
    总结:ref和out都对函数参数采用引用传递形式——不管是值类型参数还是引用类型参数,并且定义函数和调用函数时都必须显示生命该参数为ref/out形式。两者都可以使函数传回多个结果。两者区别:两种参数类型的设计思想不同,ref的目的在于将值类型参数当作引用型参数传递到函数,是函数的输入参数,并且在函数内部的任何改变也都将影响函数外部该参数的值;而out的目的在于获取函数的返回值,是输出参数,由函数内部计算得到的值再回传到函数外部,因此必须在函数内部对该参数赋值,这将冲掉函数外部的任何赋值,使得函数外部赋值毫无意义。表现为:1、out必须在函数体内初始化,这使得在外面初始化变得没意义。也就是说,out型的参数在函数体内不能得到外面传进来的初始值。
    2、ref必须在函数体外初始化。
    3、两者在函数体内的任何修改都将影响到函数体外面。再增加一个例子便于消化理解        //static void SomeFunction(int[] ints, out int i)
            //{
            //    ints[0] = 100;
            //    i = 100;
            //}        //public static int Main()
            //{
            //    int i = 0;
            //    int[] ints = { 0, 1, 2, 4, 8 };
            //    // Display the original values
            //    Console.WriteLine("i = " + i);
            //    Console.WriteLine("ints[0] = " + ints[0]);
            //    Console.WriteLine("Calling SomeFunction...");        //    // After this method returns, ints will be changed,
            //    // but i will not
            //    SomeFunction(ints,out i);
            //    Console.WriteLine("i = " + i);
            //    Console.WriteLine("ints[0] = " + ints[0]);
            //    return 0;
            //}
    输出结果请自行测试
      

  5.   

    void f(ref T p1, out T p2);p1 是一个类型为 ref T 的参数,p2 是一个带有 out 修饰(Attribute)的 类型为 T 的参数.参数: 有类型, 有无修饰(Attribute).注意类型 ref T 跟 T 是不一样的.
                   -- Don Box <.net 本质论> 学习
      

  6.   

    可以return一起搭配使用下,比较下有什么区别没
      

  7.   

    传引用void Page_Load()
    {
    int a;
    int b;
    E(out a,out b); Response.Write(a.ToString() + "|" + b.ToString());

    }void E(out int a,out int b)
    {
    a = 1;
    b = 4;
    }
      

  8.   

    加ref或out关键字的参数是.NET中是唯一能够按引用传递参数的方式...而out与ref不同之处在out参数不能初始化并且必须在方法返回之前赋值而ref参数必须初始化...至于其他都是表面现象...
      

  9.   

    out参数不能初始化
    ----------
    描述有错...out参数可以不经初始化
      

  10.   


        static void ff(ref Stream p1, out Stream p2, Stream p3, bool p4)
        {
          p2 = null;
        }    static void Main()
        {
          Type type = typeof(Program);
          MethodInfo mi = type.GetMethod("ff", BindingFlags.Static | BindingFlags.NonPublic);
          ParameterInfo[] pis = mi.GetParameters();
          Type pt = null;
          bool isout = false;
          foreach (ParameterInfo pi in pis)
          {
            Trace.WriteLine(string.Format("参数: {0}", pi.Name));
            Trace.WriteLine(string.Format("类型: {0}", pi.ParameterType.ToString()));
            Trace.WriteLine(string.Format("类型 {0} {1} byRef 的", pi.ParameterType.ToString(), pi.ParameterType.IsByRef ? "是" : "不是"));
            Trace.WriteLine(string.Format("isout:{0}", pi.IsOut.ToString()));
          }
        }
    参数: p1
    类型: System.IO.Stream&
    类型 System.IO.Stream& 是 byRef 的
    isout:False
    参数: p2
    类型: System.IO.Stream&
    类型 System.IO.Stream& 是 byRef 的
    isout:True
    参数: p3
    类型: System.IO.Stream
    类型 System.IO.Stream 不是 byRef 的
    isout:False
    参数: p4
    类型: System.Boolean
    类型 System.Boolean 不是 byRef 的
    isout:False
    参数: p5
    类型: System.Boolean&
    类型 System.Boolean& 是 byRef 的
    isout:False
    参数: p6
    类型: System.Boolean&
    类型 System.Boolean& 是 byRef 的
    isout:True
      

  11.   

        static void ff(ref Stream p1, out Stream p2, Stream p3, bool p4, ref bool p5, out bool p6)
        {
          p2 = null;
          p6 = false;
        }
      

  12.   

    out方便编程。一个函数只有一个return值。可以用out返回值。
      

  13.   

    在函数外设置一个变量,然后在函数里改变它的值
    如果是值类型,这是传值,只会改变值副本的值,值本身不会变。
    out有点像指针的意思。