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

    ref 和out的区别在面试中会常问到:

    首先:两者都是按地址传递的,使用后都将改变原来参数的数值。

    其次:ref可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空,所以你必须初始化一次。这个就是两个的区别,或者说就像有的网友说的,ref是有进有出,out是只出不进

    ref 关键字:

            会导致通过引用传递的参数,而不是值。 通过引用传递的效果是在方法中对参数的任何改变都会反映在调用方的基础参数中。 引用参数的值与基础参数变量的值始终是一样的。

     1 eg:
     2  class RefExample
     3     {
     4         static void Method(ref int i)
     5         {
     6             // Rest the mouse pointer over i to verify that it is an int.
     7             // The following statement would cause a compiler error if i
     8             // were boxed as an object.
     9             i = i + 44;
    10         }
    11 
    12         static void Main()
    13         {
    14             int val = 1;
    15             Method(ref val);
    16             Console.WriteLine(val);
    17 
    18             // Output: 45
    19         }
    20     }

    传递给 ref 参数的参数必须初始化,则通过之前。 这与 out 参数不同,参数不需要显式初始化,在通过之前。 有关更多信息,请参见 out

    选件类的成员不能具有由 ref 和 out仅不同的签名。 编译器错误,如果类型之间的两个成员的唯一区别是其中一个具有 ref 参数,另一个 out 参数。 下面的代码,例如,无法生成。

    eg:
    class CS0663_Example
    {
        // Compiler error CS0663: "Cannot define overloaded 
        // methods that differ only on ref and out".
        public void SampleMethod(out int i) { }
        public void SampleMethod(ref int i) { }
    }

    但是,重载可以执行,当一个方法具有 ref 时或 out 参数和其他具有值,参数,如下面的示例所示。

    eg:
    class RefOverloadExample
        {
            public void SampleMethod(int i) { }
            public void SampleMethod(ref int i) { }
        }

    上面的示例演示发生的情况,当您通过值类型的引用。 还可以使用 ref 关键字通过引用类型。 通过引用键入引用允许调用方法来修改引用参数引用的对象。 对象的存储位置传递给方法作为引用参数的值。 如果您修改了更改参数的存储位置,那么您也更改了基础参数的存储位置。 下面的示例通过引用类型的实例作为 ref 参数。 有关如何通过的更多信息按值引用类型和引用

    eg;
    class RefExample2
    {
        static void ChangeByReference(ref Product itemRef)
        {
            // The following line changes the address that is stored in  
            // parameter itemRef. Because itemRef is a ref parameter, the
            // address that is stored in variable item in Main also is changed.
            itemRef = new Product("Stapler", 99999);
    
            // You can change the value of one of the properties of
            // itemRef. The change happens to item in Main as well.
            itemRef.ItemID = 12345;
        }
    
        static void Main()
        {
            // Declare an instance of Product and display its initial values.
            Product item = new Product("Fasteners", 54321);
            System.Console.WriteLine("Original values in Main.  Name: {0}, ID: {1}
    ",
                item.ItemName, item.ItemID);
    
            // Send item to ChangeByReference as a ref argument.
            ChangeByReference(ref item);
            System.Console.WriteLine("Back in Main.  Name: {0}, ID: {1}
    ",
                item.ItemName, item.ItemID);
        }
    }
    
    class Product
    {
        public Product(string name, int newID)
        {
            ItemName = name;
            ItemID = newID;
        }
    
        public string ItemName { get; set; }
        public int ItemID { get; set; }
    }
    
    // Output: 
    //Original values in Main.  Name: Fasteners, ID: 54321
    
    //Back in Main.  Name: Stapler, ID: 12345

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

     1 eg:
     2 class OutExample
     3 {
     4     static void Method(out int i)
     5     {
     6         i = 44;
     7     }
     8     static void Main()
     9     {
    10         int value;
    11         Method(out value);
    12         // value is now 44
    13     }
    14 }

    尽管作为 out 参数传递的变量不必在传递之前进行初始化,但被调用的方法需要在返回之前赋一个

    实例:

    当希望方法返回多个值时,声明 out 方法很有用。 下面的示例使用 out 在一次方法调用中返回三个变量。 请注意,第三个参数所赋的值为 Null。 这样使方法可以有选择地返回值。

     
     1 eg:
     2     class OutReturnExample
     3     {
     4         static void Method(out int i, out string s1, out string s2)
     5         {
     6             i = 44;
     7             s1 = "I've been returned";
     8             s2 = null;
     9         }
    10         static void Main()
    11         {
    12             int value;
    13             string str1, str2;
    14             Method(out value, out str1, out str2);
    15             // value is now 44
    16             // str1 is now "I've been returned"
    17             // str2 is (still) null;
    18         }
    19     }

     

  • 相关阅读:
    网线
    第19次实验
    矩阵乘法
    20次试验
    视频笔记
    1
    effective C++ 条款 34:区分接口继承和实现继承
    effective C++ 条款 35:考虑virtual函数以外的其他选择
    effective C++ 条款 29:为“异常安全”而努力是值得的
    effective C++ 条款 27:尽量少做转型动作
  • 原文地址:https://www.cnblogs.com/Mengyl/p/3834135.html
Copyright © 2011-2022 走看看