Почему руководящие принципы .Net не рекомендуют использовать аргументы ref / out?

Видимо, они «сбивают с толку». Это серьезно причина? Вы можете вспомнить еще кого-нибудь?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
9
0
1 856
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

Ответ принят как подходящий

Вы видели, сколько разработчиков действительно не понимают ref / out?

Я использую их там, где они действительно необходимы, но не иначе. Обычно они полезны только в том случае, если вы хотите эффективно вернуть два или более значений - в этом случае стоит, по крайней мере, мышление о том, есть ли способ заставить метод делать только одно вместо этого. Иногда использование ref / out является наиболее подходящий подход - различные методы TryParse и т. д.

Аминь. Я прошел курс обучения C# несколько лет назад, и в группе была куча «разработчиков», которые просто не могли понять ref / out.

Stewart Johnson 18.10.2008 13:22

Думаю, этой группе «разработчиков» никогда не приходилось понимать, что такое указатели.

Alexandre Brisebois 18.10.2008 14:16

Я в основном использую ref / out для производительности; черт возьми, нет никакого смысла копировать 256-байтовую структуру 105840000 раз в секунду;)

TraumaPony 19.10.2008 11:50

Почему у вас вообще 256-байтовая структура?

Jon Skeet 19.10.2008 12:41

Это контейнер из четырех матриц 4х4.

TraumaPony 20.10.2008 10:49

ref / out автоматически означает изменчивость, и в наши дни в моде функциональное программирование с неизменяемыми значениями. Попробуйте вставить вызов Dictionary.TryGetValue в запрос LINQ. API требует объявления переменных и портит любую «беглость» в API.

Это не значит, что это «причина», но это пример «причины».

(Смотрите также

http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!181.entry

для комментариев о том, как функциональные языки работают с такими API.)

ref / out подразумевает изменяемость переменных, но не обязательно типов данных. (Я обычно использую его, например, с локальными переменными.) Беглость - это интересно - TryXXX обычно требует разного поведения для разного ветвления, что на самом деле не сочетается с беглостью :(

Jon Skeet 18.10.2008 12:13

ref / out также не работают с делегатами "Func", поэтому эти API-интерфейсы стилей труднее комбинировать / повторно использовать с некоторыми другими API-интерфейсами, использующими делегаты.

Сбивание с толку, вероятно, лучшая причина. Запутывание означает снижение ремонтопригодности и повышение вероятности появления незаметных ошибок. Я вижу их в виде, аналогичном оператору потока управления "goto". Хотя это само по себе не является плохим, оно привело к тому, что многие многие программы невозможно прочитать / понять за десятилетия.

Держитесь подальше от всего, что может сделать ваш код более запутанным, чем он должен быть.

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

На мой взгляд, они считаются запахом кода, потому что в целом есть гораздо лучший вариант: вернуть объект.

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

  • возврат класса будет означать упаковку типа значения
  • контракт метода требует, чтобы он был быстрым, поэтому упаковка / распаковка не является жизнеспособным вариантом.

Разве не достаточно причины сложности кода? Сравнивать:

int myValue;
ReadFromSomewhere(ref myValue);

К:

int myValue = ReadFromSomewhere();

Как насчет того, чтобы вернуть 2 значения. Часто проще просто вернуть 2 значения, используя аргументы byref, чем создать объект / структуру, которые будут использоваться только для единственной цели - вызова одной функции.

Kibbee 18.10.2008 22:24

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

Cristian Libardo 18.10.2008 22:30

На базовом уровне это просто из-за двух строк вместо 1. В случае с несколькими возвращаемыми значениями это совершенно разные способы возврата информации. Вы видели несколько возвращаемых значений в стиле рубина? def GetCoordinates () return 0, 20 end x, y = GetCoordinates ();

Cristian Libardo 19.10.2008 13:18

Ваши два примера не эквивалентны: вы имели в виду out, а не ref. Это влияет на ошибки компилятора и анализ управления потоком.

Jay Bazuzi 20.10.2008 10:35

Вы должны возвращать объекты, вероятно, наиболее вероятная причина, по которой они предлагают не использовать ref или out.

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

Просто подумайте, я считаю ref / out полезным, когда аргументы фиксировать состояние исполнения в целевом методе, а не захват возвращаемых данных. Рассмотрим сценарий, когда вы хотите получить сообщение об ошибке от службы, возвращающей объект Customer.

Customer GetCustomerById(int id, out string errorMessage);

Если этот метод не сработает, вы, вероятно, вернете нулевой объект Customer или выдадите исключение. Однако, если я хочу узнать причину ошибки (проверка? База данных?), Я бы использовал аргумент out. Аргумент errorMessage здесь не имеет ничего общего с данными, он просто используется для определения того, что не так с выполнением метода.

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

Мне сказали, что у сборщика мусора 1.0 были проблемы при использовании ref / out. GC в версии 2.0 (и, вероятно, не в версии 1.1) не имеет этих проблем, поэтому я обычно предполагаю, что это бесполезное наследие.

@TraumaPony Было бы хорошо, если бы вы предоставили нам источник (URL-адрес или что-то еще) для этого руководства .NET framework.

Я предполагаю, что TraumaPony ссылается на эту книгу (или ее предшественницу): amazon.com/Framework-Design-Guidelines-Conventions-Developme‌ nt /…

Neil Williams 20.10.2008 10:40

Другие вопросы по теме