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

Почему параметры "out" в .NET - плохая идея?

Почему параметры "out" в .NET - плохая идея?

Недавно меня спросили об этом, но у меня не было никакого реального ответа, кроме того, это просто излишне усложняло приложение. Какие еще причины существуют?

4b9b3361

Ответ 1

Ну, это не плохая идея, я думаю. Dictionary<K, V> имеет метод TryGetValue, который является очень хорошим примером того, почему параметры извлечения иногда бывают очень приятными.

Вы не должны чрезмерно использовать эту функцию, но это не плохая идея для каждого определения. Особенно не в С#, где вам нужно записать ключевое слово out в объявлении функции и вызове, что делает очевидным, что происходит.

Ответ 2

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

Я использую это для:

  • Возвращаемый ключ и данные IV за один вызов
  • Разделите имя человека на разные объекты (первое, второе, последнее)
  • Разделить адрес

Ответ 3

Если вы заботитесь о написании надежного кода, обнимая неизменность и устраняя побочные эффекты, тогда параметры являются абсолютно ужасной идеей. Это заставляет вас создавать изменяемые переменные, чтобы справиться с ними. (Не то, что С# в любом случае поддерживает readonly переменные уровня метода (по крайней мере, в версии, которую я использую, 3.5)).

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

Ответ 4

Out - Параметр - это плохая идея, на мой взгляд. Они увеличивают риск побочных эффектов и их трудно отлаживать. Единственное хорошее решение - результаты функции, и вот в чем проблема: для результатов функции вам нужно создать для каждого сложного результата кортеж или новый тип. Теперь это должно быть довольно легко в С#, с анонимными типами и дженериками.

И кстати: я тоже ненавижу побочные эффекты.

Ответ 5

Формулировка вопроса "Вы перестали ударить своей жене?" разновидности, предполагает, что параметры должны быть плохой идеей. Есть случаи, когда параметры могут быть злоупотреблены, но...

  • Они действительно очень хорошо подходят для языка С#. Они похожи на параметры ref, за исключением того, что метод гарантированно назначает ему значение, и вызывающему абоненту не нужно инициализировать переменную.

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

  • Они отлично подходят для шаблона TryParse, а также предоставляют метаданные для других вещей, например, в случае SQL-CLR, где параметры передаются вне параметров сигнатуры хранимой процедуры.

Ответ 6

Я бы сказал, что ваш ответ на месте; это обычно ненужное осложнение, и обычно это более простой дизайн. Большинство методов, с которыми вы работаете в .NET, не изменяют свои входные параметры, поэтому использование одноразового метода, использующего синтаксис, немного запутанно. Код становится немного менее интуитивным, и в случае плохо документированного метода мы не знаем, что метод делает с входным параметром.

Кроме того, сигнатуры методов с отсутствующими параметрами инициируют нарушение кода /FxCop, если это метрика, о которой вы заботитесь. В большинстве случаев существует лучший способ достижения цели метода, который использует параметр "out", и метод может быть реорганизован для возврата интересной информации.

Ответ 7

Не всегда плохая идея использовать параметры. Обычно для кода, который пытается создать объект на основе какой-либо формы ввода, рекомендуется создать метод Try с параметрами out и boolean return, а не заставить потребитель метода обернуть try catch блоки на всем протяжении, не говоря уже о лучшей производительности. Пример:

bool TryGetSomeValue(out SomeValue value, [...]);

это случай, когда параметры являются хорошей идеей.

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

void CreateNullProjectionMatrix(out Matrix matrix);

эта версия позволяет избежать дорогостоящего структурированного копирования.

Но, если только не требуется по определенной причине, этого следует избегать.

Ответ 8

Ну, для этого нет четкого ответа, но простым вариантом использования для параметра out будет "Int.TryParse(" 1 ", out myInt)"

Задача метода XXX.TrayParse - это преобразование значения некоторого типа в другой тип, он возвращает вам логический флаг, указывающий на успешность или неудачу преобразования, которая является одной частью, другая часть представляет собой преобразованное значение, который переносится параметром out в этом методе.

Этот метод TryParse был представлен в .NET 2.0, чтобы понять, что XXX.Parse будет через исключение, если преобразование завершится с ошибкой, и вы должны попробовать try/catch вокруг инструкции.

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

В любом случае Microsoft говорит "Избегайте использования параметров", в своем руководстве по дизайну проверьте эту страницу msdn http://msdn.microsoft.com/en-us/library/ms182131(VS.80).aspx

Ответ 9

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

Единственное исключение - если возвращаемые данные несколько третичные, например, nullool bool. Это может быть true/false или undefined. Параметр out может помочь решить аналогичную идею для других логических типов.

Другой, который я иногда использую, - это когда вам нужно получить информацию через интерфейс, который не позволяет использовать "лучший" метод. Например, использование библиотек доступа .Net и ORM. Когда вам нужно вернуть обновленный графический объект (после UPDATE) или новый генерируемый RDBMS идентификатор (INSERT), а также количество строк, на которые повлияла инструкция. SQL возвращает все это в одном выражении, поэтому несколько вызовов метода не будут работать, так как ваш уровень данных, библиотека или ORM вызывает только одну общую команду INSERT/UPDATE и не может хранить значения для последующего поиска.

Идеальные методы, такие как никогда не использовать списки динамических параметров или параметры, не всегда практичны все время. Опять же, подумайте дважды, если параметр out - это действительно правильный способ сделать это. Если да, то идите. (Но удостоверьтесь, что это хорошо!)

Ответ 10

Я бы сказал, что ответ, который вы дали, - о лучшем, что есть. Вы всегда должны проектировать от параметров out, если это возможно, потому что это обычно делает код излишне сложным.

Но это справедливо для любого шаблона. Если это не нужно, не используйте его.

Ответ 11

Я не думаю, что они есть. Неправильное использование их - плохая идея, но это касается любой практики/техники кодирования.

Ответ 12

Ему нравится, как парень Tanqueray любит говорить - все в меру.

Я определенно хотел бы подчеркнуть чрезмерное использование, поскольку это привело бы к "написанию c в С#" почти так же, как можно писать java в Python (где вы не обнимаете шаблоны и идиомы, которые делают новый язык особенным, а вместо этого просто задумываясь на своем старом языке и переходя к новому синтаксису). Тем не менее, как всегда, если это поможет вашему коду быть более элегантным и иметь больше смысла, выкарабкайтесь.

Ответ 13

Я не думаю, что есть настоящая причина, хотя я не видел, чтобы она часто использовала (кроме P/Invoke calls).

Ответ 14

Необходимо указать ключевое слово out (см. SortedDictionart.TryGetValue). Он подразумевает передачу по ссылке и также сообщает компилятору следующее:

int value;
some_function (out value);

в порядке и что some_function не использует унифицированное значение, которое обычно является ошибкой.

Ответ 15

Я думаю, что в некоторых сценариях это хорошая идея, потому что они позволяют возвращать более одного объекта из функции, например:

DateTime NewDate = new DateTime();
if (DateTime.TryParse(UserInput, out NewDate) == false) {
    NewDate = DateTime.Now;
}

Очень полезно:)

Ответ 16

Я бы согласился с GateKiller. Я не могу представить, что параметры слишком плохие, если Microsoft использовала их как часть базовой библиотеки. Но, как и все, лучше всего в меру.

Ответ 17

Некоторые языки вне .NET используют их как макросы do-nothing, которые просто дают программисту информацию о том, как используются параметры в функции.

Ответ 18

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

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

Ответ 19

'out' отлично!

Он делает оператор clear, что параметр содержит значение, возвращаемое методом.

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

Ответ 20

Я думаю, что основная причина заключается в том, что "... хотя значения возврата являются обычным и широко используемым, правильное применение параметров out и требует промежуточного проектирования и навыки кодирования. Архитекторы библиотек, которые проектируют для широкой аудитории , не должны ожидать, что пользователи будут обрабатывать рабочие с параметрами out или ref.

Пожалуйста, прочитайте больше на: http://msdn.microsoft.com/en-us/library/ms182131.aspx

Ответ 21

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