Разница out & ref - зачем два разных оператора?
Недавно надо было вернуть результат и з функции в виде параметра. Знал о существовании таких вещей как 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 внутри вызываемой ф-ии.
Компании из статьи
Microsoft Украина | Украинское подразделение компании Microsoft. |