zoukankan      html  css  js  c++  java
  • C#中Ref和out的使用区别

    转载:http://msdn.microsoft.com/zh-cn/vcsharp/aa336814(en-us).aspx

    总结:
    1. out传参数前不必分配值,而ref必须赋值再传递。
    2. 如果参数(out或ref)太多,建议使用Struct或Class代替。

    Why does C# have both 'ref' and 'out'?

    Ref and out parameter passing modes are used to allow a method to alter variables passed in by the caller. The difference between ref and out is subtle but important. Each parameter passing mode is designed to apply to a slightly different programming scenario. The important difference between out and ref parameters is the definite assignment rules used by each.

    The caller of a method which takes an out parameter is not required to assign to the variable passed as the out parameter prior to the call; however, the callee is required to assign to the out parameter before returning.

    Here's a simple example:

    class OutExample
    {
          // Splits a string containing a first and last name separated
          // by a space into two distinct strings, one containing the first name and one containing the last name

          static void SplitName(string fullName, out string firstName, out string lastName)
          {
                // NOTE: firstName and lastName have not been assigned to yet.  Their values cannot be used.
                int spaceIndex = fullName.IndexOf(' ');
                firstName = fullName.Substring(0, spaceIndex).Trim();
                lastName = fullName.Substring(spaceIndex).Trim();
          }

          static void Main()
          {
                string fullName = "Yuan Sha";
                string firstName;
                string lastName;

                // NOTE: firstName and lastName have not been assigned yet.  Their values may not be used.
                SplitName(fullName, out firstName, out lastName);
                // NOTE: firstName and lastName have been assigned, because the out parameter passing mode guarantees it.

                System.Console.WriteLine("First Name '{0}'. Last Name '{1}'", firstName, lastName);
          }
    }

    One way to think of out parameters is that they are like additional return values of a method. They are very convenient when a method returns more than one value, in this example firstName and lastName. Out parameters can be abused however. As a matter of good programming style if you find yourself writing a method with many out parameters then you should think about refactoring your code. One possible solution is to package all the return values into a single struct.

    In contrast ref parameters are considered initially assigned by the callee. As such, the callee is not required to assign to the ref parameter before use. Ref parameters are passed both into and out of a method.

    Here's an example:

    class RefExample
    {
          static object FindNext(object value, object[] data, ref int index)
          {
                // NOTE: index can be used here because it is a ref parameter
                while (index < data.Length)
                {
                      if (data[index].Equals(value))
                      {
                            return data[index];
                      }
                       index += 1;
                }
                 return null;
          }

          static void Main()
          {
                object[] data = new object[] {1,2,3,4,2,3,4,5,3};

                int index = 0;
                // NOTE: must assign to index before passing it as a ref parameter
                while (FindNext(3, data, ref index) != null)
                {
                      // NOTE: that FindNext may have modified the value of index
                      System.Console.WriteLine("Found at index {0}", index);
                      index += 1;
                }

                System.Console.WriteLine("Done Find");
          }
    }

    The two parameter passing modes addressed by out and ref are subtly different, however they are both very common. The subtle difference between these modes leads to some very common programming errors. These include:

    • not assigning a value to an out parameter in all control flow paths
    • not assigning a value to variable which is used as a ref parameter

    Because the C# language assigns different definite assignment rules to these different parameter passing modes, these common coding errors are caught by the compiler as being incorrect C# code.

    The crux of the decision to include both ref and out parameter passing modes was that allowing the compiler to detect these common coding errors was worth the additional complexity of having both ref and out parameter passing modes in the language.

  • 相关阅读:
    全面分析再动手的习惯:链表的反转问题(递归和非递归方式)
    Gatech OMSCS的申请和学习之奥妙
    java线程安全之并发Queue
    一篇文章看懂Java并发和线程安全
    java并发之如何解决线程安全问题
    Java并发/多线程系列——线程安全篇(1)
    当面试官问线程池时,你应该知道些什么?
    java 线程池 使用实例
    多线程-Executors和Executor,线程池
    从阿里Java开发手册学习线程池的正确创建方法
  • 原文地址:https://www.cnblogs.com/simonhaninmelbourne/p/1535593.html
Copyright © 2011-2022 走看看