Разница out & ref - зачем два разных оператора?

пятница, 6 марта 2009, Oleksandr Reminnyi

Недавно надо было вернуть результат и з функции в виде параметра. Знал о существовании таких вещей как ref & out. Но в этот раз заинтересовался еще и разницей между ними.

Разница тонка, но важна - заключаеться в способах присвоения значений.

Out - вызывающей функции не обязательно инициализировать значение out параметра, в то время как вызываемая обязательно должна его инициализировать до возвращения. Out - тот же return, только когда нужно вернуть более одного результата, как в примере: firstName, lastName.

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);
   }
}

В то же время ref параметру нужно присвоить значение еще  до вызова метода; ref параметр позволяет не только получать значение как результат функции, но и передавать значение внутрь функции.

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");
   }
}

Частые ошибки (отлавливаються компилятором):

 - неприсвоение значения параметру ref до передачи в ф-ию,

 - неприсвоение значения параметру out внутри вызываемой ф-ии. 

источник MSDN

Компании из статьи


Microsoft Украина


Сайт:
http://www.microsoft.com/ukr/ua/

Microsoft Украина Украинское подразделение компании Microsoft.

Ищите нас в интернетах!

Комментарии

Свежие вакансии