Почему «использование системы»; не считается плохой практикой? - PullRequest
47 голосов
/ 03 февраля 2020

У меня есть опыт работы с C ++, и я полностью понимаю и согласен с ответами на этот вопрос: Почему «используется пространство имен std;» считается плохой практикой?

Так что я удивлен, что, имея некоторый опыт работы с C# сейчас, я вижу прямо противоположное: using Some.Namespace; буквально используется везде. Всякий раз, когда вы начинаете использовать тип, вы сначала добавляете директиву using для его пространства имен (если его там еще нет). Я не могу вспомнить, чтобы видел .cs -файл, который не начинался с using System; using System.Collections.Generic; using X.Y.Z; etc.... Фактически, если вы добавляете новый файл с помощью мастера Visual Studio, он автоматически добавляет туда некоторые директивы using, даже если они вам вообще не нужны. Так что, хотя в сообществе C ++ вас в основном линчуют, C# даже поощряет это делать. По крайней мере, так мне кажется.

Теперь я понимаю, что использование директив в C# и C ++ - это не одно и то же. Кроме того, я понимаю, что одна из самых неприятных вещей, которые вы можете сделать с using namespace в C ++, а именно поместить ее в файл заголовка, не имеет аналогично неприятного аналога в C# из-за отсутствия концепции заголовочных файлов и #include.

Однако, несмотря на их различия, использование директив в C# и C ++ преследует одну и ту же цель: приходится только постоянно набирать SomeType, а не намного дольше Some.Namespace.SomeType ( в C ++ с :: вместо .). И с этой же целью мне кажется, что опасность та же: именование коллизий.

В лучшем случае это приводит к ошибке компиляции, поэтому вам «только» нужно ее исправить. В худшем случае, он все еще компилируется, и код молча делает разные вещи, чем вы предполагали. Итак, мой вопрос: Почему (по-видимому) используются директивы, которые считаются столь неравномерно плохими в C# и C ++?

Некоторые идеи ответа, которые у меня есть (ни одно из них действительно не удовлетворяет меня хотя):

  • Пространства имен имеют тенденцию быть намного длиннее и гораздо более вложенными в C#, чем в C ++ (std против System.Collection.Generic). Таким образом, есть больше желания и больше выгоды в устранении шума в коде таким образом. Но даже если это так, этот аргумент применяется только тогда, когда мы смотрим на стандартные пространства имен. Пользовательские могут иметь любое короткое имя, которое вам нравится, как в C#, так и в C ++.

  • Пространства имен кажутся гораздо более «мелкозернистыми» в C#, чем в C ++. Например, в C ++ вся стандартная библиотека содержится в std (плюс несколько крошечных вложенных пространств имен, таких как chrono), в то время как в C# у вас есть System.IO, System.Threading, System.Text et c. Таким образом, риск возникновения коллизий именования меньше. Тем не менее, это только внутреннее чувство. На самом деле я не посчитал, сколько имен вы «импортируете» с using namespace std и using System. И снова, даже если это так, этот аргумент применяется только при рассмотрении стандартных пространств имен. Ваши собственные могут быть спроектированы так же хорошо, как вы, sh, как в C#, так и в C ++.

Есть еще аргументы? Я особенно заинтересован в реальных фактах (если они есть), а не в мнениях.

Ответы [ 2 ]

28 голосов
/ 03 февраля 2020

Почему «используется система»; не считается плохой практикой?

"использование системы"; не универсально не считается плохой практикой. См. Например: Почему бы вам не использовать директиву 'using' в C#?

Но может быть и так, что она не считается вполне плохой как using namespace std. Возможно, потому что:

  1. C# не имеет заголовочных файлов. Редко «включать» один C# исходный файл в другой, используя препроцессор.

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

  3. В C# нет глобальных функций или переменных. Таким образом, число глобальных идентификаторов, как правило, довольно мало, в отличие от C ++, который имеет такие: Кроме того, типично использовать библиотеки C (часто косвенно), которые не имеют пространств имен, и поэтому помещают все их имена в глобальное пространство имен.

  4. Насколько я знаю, C# не имеет зависимого от аргумента поиска. ADL в сочетании с сокрытием имени, перегрузкой et c. может привести к случаям, когда некоторые программы не затронуты конфликтом имен, в то время как другие подвержены незначительному влиянию, и выявление всех угловых случаев невозможно при тестировании.

Из-за этих различий «использование система «; вероятность конфликта имен ниже, чем using namespace std.


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

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

0 голосов
/ 03 февраля 2020

Однако, несмотря на их различия, использование директив в C# и C ++ служит одной и той же цели, которая заключается только в том, чтобы постоянно вводить SomeType, а не намного более длинном Some.Namespace.SomeType (в C ++ с :: вместо .). И с этой же целью мне представляется опасность: называть коллизии.

Да, но вы не экспортировали этой опасности (читай: заставлять других действовать) с этим), из-за:

Теперь я понимаю, что использование директив в C# и C ++ - это не одно и то же. Кроме того, я понимаю, что одна из самых неприятных вещей, которые вы можете сделать с использованием пространства имен в C ++, а именно поместить его в файл заголовка, не имеет эквивалента в C# из-за отсутствия концепции файлов заголовков и #include.

Так что это совсем другая категория вещей.

Кроме того, C ++ не «предназначен» для разработки в IDE так же, как C#. C# в основном всегда написан в Visual Studio с его Intellisense и еще много чего. Он предназначен для использования людьми, которые его создали. Независимо от того, сколько людей используют IDE для разработки на C ++, она не предназначена для этого варианта использования в качестве непреодолимой проблемы.

Пространства имен кажутся гораздо более "мелкозернистыми" в C#, чем в C ++.

Да, это тоже. using namespace std и using System.Collection.Generic несопоставимы.

Так что не сравнивайте их!

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