zoukankan      html  css  js  c++  java
  • .NET中,在方法参数的类型前加一个OUT是做什么用的

    话说古时候,在一个名字叫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;
    5
    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

    输出结果:

    默认空值输出:

    rrrrrref

    0oooooout

    refTestStr:rrrrrref

    outTestStr:0oooooout

    -------------------

    从新赋值:refTestStr = "1";outTestStr = "2";

    1rrrrrref

    0oooooout

    refTestStr:1rrrrrref

    outTestStr:0oooooout

    -------------------

    从新赋值:refTestStr = "3";outTestStr = "4";

    3rrrrrref

    0oooooout

    refTestStr:3rrrrrref

    outTestStr:0oooooout

    -------------------

    --------params-------

    System.String[]

    str_a

    0_2

    1_3

    2_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;
    //}

    输出结果请自行测试
  • 相关阅读:
    本周总结
    团队组队
    ListView之checkbox错位问题解决
    ListView
    ScrollView(滚动条)
    elementui中自定义Select选择器样式自定义
    element-ui中Select 选择器列表内容居中
    element-ui中Select 选择器去除点击时的淡蓝色边框
    vue和uni-app不同的类型绑定不同的类名
    根据年月日获取星期几
  • 原文地址:https://www.cnblogs.com/yuhuameng/p/5047416.html
Copyright © 2011-2022 走看看