代码之家  ›  专栏  ›  技术社区  ›  Pratik Deoghare

为什么在C#中引用和输出?

c#
  •  15
  • Pratik Deoghare  · 技术社区  · 16 年前

    ref ,调用代码需要初始化传递的参数,但使用关键字 out 我们不需要这样做。

    • 我们为什么不使用 出来
    • 两者的确切区别是什么?
    • 请举例说明我们需要使用的情况 裁判 不能使用 出来
    7 回复  |  直到 10 年前
        1
  •  16
  •   Vinay Sajip    16 年前

    MSDN article . 从该职位:

    两种参数传递模式 收件人 out ref 微妙地 不同的是,它们都很相似

    1. 不将值赋给 所有控制流路径中的参数
    2. 它被用作 参数

    不同的确定赋值规则 这些不同的参数传递 在模式中,这些常见的编码错误是 被编译器捕获为

    决定的关键包括 裁判 参数传递 模式是允许编译器 值得付出额外的复杂性 兼有 出来

        2
  •  15
  •   i_am_jorf    16 年前

    out 是一种特殊形式的 ref

    出来 变量在方法返回之前被赋值,并且变量在赋值之前不被使用。

    两个例子 出来 不起作用但是 做:

    void NoOp(out int value) // value must be assigned before method returns
    {
    }
    
    void Increment(out int value) // value cannot be used before it has been assigned
    {
        value = value + 1;
    }
    
        3
  •  8
  •   JohnB    14 年前

    ref out

    我的答案是以下两页的摘要:

    1. ref (C# Reference)
    2. out (C# Reference)

    1. 方法定义和调用方法都必须显式使用 裁判 /
    2. 这两个关键字都会导致通过引用传递参数( 偶数值类型
    3. 然而,这是不可能的 boxing
    4. 出来 裁判 ,因为属性实际上是方法
    5. 裁判 裁判 出来 论点

    明显的差异

    裁判

    1. 可以使用将值传递给方法

    出来

    1. 在传递之前不必初始化
    2. 无法使用将值传递给方法

    无法编译,因为方法签名的唯一区别是 / :

    public void Add(out int i) { }
    public void Add(ref int i) { }
    

    使用 关键词:

    public void PrintNames(List<string> names)
    {
      int index = 0; // initialize first (#1)
    
      foreach(string name in names)
      {
        IncrementIndex(ref index);
        Console.WriteLine(index.ToString() + ". " + name);
      }
    }
    
    public void IncrementIndex(ref int index)
    {
      index++; // initial value was passed in (#2)
    }
    

    使用 出来 关键词:

    public void PrintNames(List<string> names)
    {
      foreach(string name in names)
      {
        int index; // not initialized (#1)
    
        GetIndex(out index);
        Console.WriteLine(index.ToString() + ". " + name);
      }
    }
    
    public void GetIndex(out int index)
    {
      index = IndexHelper.GetLatestIndex(); // needs to be assigned a value (#2 & #3)
    }
    

    1. 在我看来,使用 关键字类似于使用 Output 的枚举值 ParameterDirection 用于在ADO.NET中声明输出参数
    2. C#中的数组是通过引用传递的,但是为了重新分配数组引用以影响调用代码中的引用 裁判 必须使用关键字

    例子:

    public void ReassignArray(ref int[] array)
    {
      array = new int[10]; // now the array in the calling code
                           // will point to this new object
    }
    

    有关引用类型与值类型的更多信息,请参见 Passing Reference-Type Parameters (C# Programming Guide)

        4
  •  1
  •   i_am_jorf    16 年前

    public void SquareThisNumber(ref int number) 
    {
       number = number * number;
    }
    
    int number = 4;
    SquareThisNumber(ref number);
    

    这是我们想要的 number 作为一个in-out变量,所以我们使用 ref out ,编译器会给出一个错误,说明我们初始化了

        5
  •  1
  •   Brad Bruce    16 年前

    ref关键字允许您更改参数的值。被调用的方法可以是调用链中的中间链接。使用out关键字的方法只能在调用链的开头使用。

    另一个优点是,可以在方法的逻辑中使用现有值,并且仍然保留返回值。

    在Oracle中,函数具有显式的In/OUT和OUT参数(默认值和未设置方向时得到的值)。等效值为正常值(仅为参数)、ref[参数]和out[参数]。

        6
  •  0
  •   Preet Sangha    16 年前

        7
  •  0
  •   Peter Mortensen Pieter Jan Bonestroo    10 年前

    当我们在调用以 out 关键字,它对待它完全不同,就像我们不将它传递给方法一样。相反,我们实际上是将out变量的值从方法的definition部分收集(outing)到我们调用该方法的methodout变量参数。

    所以 out variable

    出来 当需要从特定方法返回多个值时,使用变量。

    当发生意外时 ref 变量我们需要首先初始化它,因为它的内存位置作为参数传递给方法定义。想一想如果我们在通过之前没有初始化它会发生什么?