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





Вы видели, сколько разработчиков действительно не понимают ref / out?
Я использую их там, где они действительно необходимы, но не иначе. Обычно они полезны только в том случае, если вы хотите эффективно вернуть два или более значений - в этом случае стоит, по крайней мере, мышление о том, есть ли способ заставить метод делать только одно вместо этого. Иногда использование ref / out является наиболее подходящий подход - различные методы TryParse и т. д.
Думаю, этой группе «разработчиков» никогда не приходилось понимать, что такое указатели.
Я в основном использую ref / out для производительности; черт возьми, нет никакого смысла копировать 256-байтовую структуру 105840000 раз в секунду;)
Почему у вас вообще 256-байтовая структура?
Это контейнер из четырех матриц 4х4.
ref / out автоматически означает изменчивость, и в наши дни в моде функциональное программирование с неизменяемыми значениями. Попробуйте вставить вызов Dictionary.TryGetValue в запрос LINQ. API требует объявления переменных и портит любую «беглость» в API.
Это не значит, что это «причина», но это пример «причины».
(Смотрите также
http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!181.entry
для комментариев о том, как функциональные языки работают с такими API.)
ref / out подразумевает изменяемость переменных, но не обязательно типов данных. (Я обычно использую его, например, с локальными переменными.) Беглость - это интересно - TryXXX обычно требует разного поведения для разного ветвления, что на самом деле не сочетается с беглостью :(
ref / out также не работают с делегатами "Func", поэтому эти API-интерфейсы стилей труднее комбинировать / повторно использовать с некоторыми другими API-интерфейсами, использующими делегаты.
Сбивание с толку, вероятно, лучшая причина. Запутывание означает снижение ремонтопригодности и повышение вероятности появления незаметных ошибок. Я вижу их в виде, аналогичном оператору потока управления "goto". Хотя это само по себе не является плохим, оно привело к тому, что многие многие программы невозможно прочитать / понять за десятилетия.
Держитесь подальше от всего, что может сделать ваш код более запутанным, чем он должен быть.
Сказав это, эти ключевые слова существуют, вероятно, потому, что разработчики фреймворка видели необходимость в таких вещах. Используйте их, если нет подходящего решения, но по возможности избегайте их.
На мой взгляд, они считаются запахом кода, потому что в целом есть гораздо лучший вариант: вернуть объект.
Если вы заметили, в библиотеке .NET они используются только в некоторых особых случаях, а именно в сценариях, подобных трипарс, где:
Разве не достаточно причины сложности кода? Сравнивать:
int myValue;
ReadFromSomewhere(ref myValue);
К:
int myValue = ReadFromSomewhere();
Как насчет того, чтобы вернуть 2 значения. Часто проще просто вернуть 2 значения, используя аргументы byref, чем создать объект / структуру, которые будут использоваться только для единственной цели - вызова одной функции.
Верно, но я не имел в виду несколько аргументов. В большинстве случаев я бы предпочел структуру, если бы я был пользователем этой функции.
На базовом уровне это просто из-за двух строк вместо 1. В случае с несколькими возвращаемыми значениями это совершенно разные способы возврата информации. Вы видели несколько возвращаемых значений в стиле рубина? def GetCoordinates () return 0, 20 end x, y = GetCoordinates ();
Ваши два примера не эквивалентны: вы имели в виду out, а не ref. Это влияет на ошибки компилятора и анализ управления потоком.
Вы должны возвращать объекты, вероятно, наиболее вероятная причина, по которой они предлагают не использовать 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 /…
Аминь. Я прошел курс обучения C# несколько лет назад, и в группе была куча «разработчиков», которые просто не могли понять ref / out.