Возвращаемые значения - это почти всегда правильный выбор, когда методу нечего возвращать. (На самом деле, я не могу думать о каких-либо случаях, когда у меня был бы . Если бы у меня был выбор, у меня был бы метод void с параметром out
. Способы декомпонирования, поддерживаемые языком C# 7, действуют очень, очень редко исключение из этого правила.)
Помимо всего прочего, он останавливает абонента от необходимости объявить переменную отдельно:
int foo;
GetValue(out foo);
против
int foo = GetValue();
Out значения также предотвратить метод цепочки, как это:
Console.WriteLine(GetValue().ToString("g"));
(В самом деле, это одна из проблем с установщиками недвижимости, и именно поэтому bui lder использует методы, которые возвращают строитель, например. myStringBuilder.Append(xxx).Append(yyy)
.)
Кроме того, параметры с параметрами немного сложнее использовать с отражением и, как правило, также затрудняют тестирование. (Больше усилий обычно делается для упрощения измельчения возвращаемых значений, чем из параметров). В принципе, я ничего не могу придумать, что они делают проще ...
Возвращаемые значения FTW.
EDIT: С точки зрения того, что происходит ...
В основном, когда вы передаете в качестве аргумента для параметра «вне», вы должны передать в переменной. (Элементы массива также классифицируются как переменные.) Метод, который вы вызываете, не имеет «новой» переменной в его стеке для параметра - он использует вашу переменную для хранения. Любые изменения в переменной сразу видны. Ниже приведен пример, показывающий разницу:
using System;
class Test
{
static int value;
static void ShowValue(string description)
{
Console.WriteLine(description + value);
}
static void Main()
{
Console.WriteLine("Return value test...");
value = 5;
value = ReturnValue();
ShowValue("Value after ReturnValue(): ");
value = 5;
Console.WriteLine("Out parameter test...");
OutParameter(out value);
ShowValue("Value after OutParameter(): ");
}
static int ReturnValue()
{
ShowValue("ReturnValue (pre): ");
int tmp = 10;
ShowValue("ReturnValue (post): ");
return tmp;
}
static void OutParameter(out int tmp)
{
ShowValue("OutParameter (pre): ");
tmp = 10;
ShowValue("OutParameter (post): ");
}
}
Результаты:
Return value test...
ReturnValue (pre): 5
ReturnValue (post): 5
Value after ReturnValue(): 10
Out parameter test...
OutParameter (pre): 5
OutParameter (post): 10
Value after OutParameter(): 10
Разница заключается в «пост» шаг - то есть после локальной переменной или параметра было изменено. В тесте ReturnValue это не имеет значения для статической переменной value
. В тесте OutParameter значение переменной value
изменяется по строке tmp = 10;
Я бы хотел, чтобы у C# было несколько возвращаемых значений, например Python. – Trap
@Trap Вы можете вернуть «Tuple», если хотите, но общий консенсус в том, что если вам нужно вернуть несколько вещей, вещи обычно связаны каким-то образом, и это отношение обычно лучше всего выражается как класс. – Pharap
@Pharap Tuples в C# в его текущей форме просто уродливые, но это только мое мнение. С другой стороны, «общий консенсус» ничего не значит с точки зрения удобства использования и производительности. Вы бы не создали класс для возврата нескольких значений по той же причине, что вы не создали бы класс, чтобы вернуть пару значений в качестве параметра ref/out. – Trap