Подтвердить что ты не робот

Изменить параметр метода в методе или вернуть результат

В чем разница между

private void DoSomething(int value) {
    value++;
}

и

private int DoSomething(int value) {
   return value++;
}

при использовании как

DoSomething(value);

против

value = DoSomething(value);
4b9b3361

Ответ 1

Вы говорите о разнице между передачей по ссылке и передачей по значению, которая концептуально похожа на идею типов типов и ссылочных типов strong > .

Если вы передадите метод значения в метод, вы должны использовать второй пример; в противном случае вы просто увеличиваете целое число, существующее внутри области DoSomething(). Попробуйте: если вы выполните свой первый пример, после выполнения DoSomething() значение вашего int будет неизменным.

Однако, если вы передаете нечто иное, чем тип значения (скажем, объект foo), вы фактически передаете ссылку исходному объекту. Все, что вы делаете с ней внутри DoSomething(), вступит в силу вне метода, так как вы все еще ссылаетесь на один и тот же объект.

Вы можете выполнить то, что вы пытаетесь в первом примере, написав:

void DoSomething(ref int value)

Это указывает .NET передавать ссылку на элемент независимо от того, является ли это типом значения.

Для более детального просмотра см. эту запись в Типы значений vs Reference Types в MSDN.

Кроме того, в качестве zodoz указывает (верхняя позиция соответственно), возвращая value++, вы возвращаетесь и затем увеличиваете. Чтобы вернуть добавочное значение, используйте ++value.

Ответ 2

Возвращает значение.

Почему?

Корректность, читаемость и самодокументация

Преднамеренный и понятный код лучше, чем код побочного эффекта. Рассмотрим:

float area = pi * Square(r);

против.

Square(r);
float area = pi * r;
// ... intervening code
float x = r * 5;  // did you mean to use the original r or r-squared here?

Также рассмотрим преимущества скрупулезности с помощью композиционной способности в первом примере.

Рассмотрим сами методы, сравните:

int DoSomething(int value)
   { return value+1; }

Это довольно правильно. против.

void DoSomething(int value)
   { value++; }

Что кажется правильным и будет компилироваться просто отлично, но на самом деле просто нет-op. Что вы действительно хотите, так это:

void DoSomething(ref int value)
   { value++; }

// client code:
DoSomething(ref a);

Переменные - Дешевые

Многие хорошо известные переменные предпочтительнее нескольких повторно используемых переменных общего назначения. Сопротивляйтесь соблазну преждевременной оптимизации, вероятность того, что вам нужно сократить количество локальных переменных для повышения производительности вашей системы, является космически крошечной. Опять же, переменные являются дешевыми, НЕ ПОЛУЧАЮТ ПЕРЕМЕННЫЕ!

Тестируемость

Рассмотрим:

Assert.IsTrue(Square(2) == 4);

против.

float a = 2;
Square(a);
Assert.IsTrue(a == 4);

Есть много других преимуществ, чтобы избежать мутации, предпочитая возвращать значение. Это не просто случайность, которую математика определяет функцию как отображение входных значений в выходные значения.

Ответ 3

Все остальные, кажется, предлагают разницу в передаче переменной, но я заметил что-то другое:

Если отображаемый примерный код - это упрощение того, что вы уже просматриваете, то вы можете заметить, что во втором примере:

private int DoSomething(int value) {
    return value++;
}

value вернет приращение , затем. Поэтому, если вы выполните следующее:

public Main() {
    int val = 1;
    Console.writeln(DoSomething(val));
}

Ваш результат будет 1.

Сообщите мне, если это вообще поможет.

Ответ 4

Просто первый не будет работать, потому что вы работаете с копией значения.

Вы можете сделать что-то вроде

private int DoSomething(ref int value)
{
  value++;
}

и назовите его как

DoSomething(ref value);

Это изменяет значение, которое должно быть передано по ссылке. Но на самом деле единственной причиной для этого является то, что вы хотите вернуть несколько функций из своей функции. И обычно есть лучшие способы.

Для получения дополнительных бонусных знаний также есть ключевое слово out, похожее на ref, но не требующее инициализации значения.

Ответ 5

В первом примере параметр int value увеличивается, но при уничтожении метода он не может получить значение вне метода, если вы не используете ref или out.

Например:

private int DoSomething(ref int value) {
   return value++;
}

// ...
int myValue = 5;
DoSomething(ref myValue);
// Now myValue is 6.

Режимы передачи и выхода параметров используются, чтобы позволить способу изменять переменные, переданные вызывающим методом. Основное различие между ref и out может быть тонким, но это важно.

Каждый режим передачи параметров предназначен для удовлетворения различных потребностей программирования.

Вызывающий метод, который принимает параметр out, не требуется назначать переменной, переданной как параметр out перед вызовом; однако, требуется, чтобы назначить параметр out перед возвратом.

Один из способов определения параметров - это то, что они похожи на дополнительные возвращаемые значения метода. Они удобны, когда метод должен возвращать более одного значения.

Параметры ref заставляют аргументы передаваться по ссылке. Эффект заключается в том, что любые изменения параметра в методе будут отражаться в этой переменной, когда управление переходит к вызывающему методу.

Не путайте понятие передачи по ссылке с понятием ссылочных типов.

Оба понятия не связаны; параметр метода может быть изменен с помощью ref независимо от того, является ли он типом значения или ссылочным типом, бокс типа значения, когда он передается по ссылке.

Ответ 6

В большинстве языков программирования вам нужно будет изменить свою функцию void, передав параметр по ссылке. Функция обычно не может изменять значение своих параметров; вместо этого он создает копию параметра и работает с этим.

Чтобы работать с фактической переменной, вам нужно изменить заголовок функции, чтобы принять ссылку на переменную с предыдущим амперсандом (&) следующим образом:

private void DoSomething(int &value)

Надеюсь, что это поможет!

Ответ 7

Поскольку вы используете postfix ++, возвращаемое значение является исходным значением числа. Кроме того, поскольку вы передаете копию номера, а не самого номера (то есть по ссылке), изменения, внесенные в значение, не влияют на переданную вами переменную.

Итак, такая программа:

int value=1;
std::cout<<value<<std::endl;
value = DoSomething(value);
std::cout<<value<<std::endl;

DoSomething(value);
std::cout<<value<<std::endl;

Должно выводиться следующим образом:

1
1
1

Если вы должны использовать префикc++ в возвращаемом или если вы должны были пройти по ссылке в не возвращающей функции, то одна и та же программа выводит следующим образом.

1
2
3

Надеюсь, что это поможет.