Есть ли в C# слишком много языковых возможностей?

Это обсуждение, которое время от времени появляется в нашей команде. В то время как некоторые быстро освоили функции C# 3.0, другие придерживаются классических приемов.

Некоторые никогда не используют Linq, считают, что лямбда-выражения сбивают с толку, а yield "страшен". Иногда они едва могут понять код, написанный людьми, использующими все новые функции. Можно просто сказать, что они не владеют языком и должны изучать его.

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

Вероятно, неполный список возможностей C#

  • классы, структуры, примитивные типы, массивы, бокс, интерфейсы, наследование (абстрактное, виртуальное, новое, запечатанное), свойства, обнуляемые
  • исключения
  • дженерики
  • многопоточность, замки
  • отражение
  • делегаты, события, анонимные делегаты
  • итераторы
  • лямбда-выражения
  • методы расширения
  • LINQ

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

Лично мне нравится почти каждая функция C#, и мне нравится короткий и красивый код, который я могу написать на этом языке. Но мне не нужно учить это с нуля.

Мне интересно ваше мнение и ваш опыт обучения или преподавания C#. Есть ли уже слишком много функций? Все еще отсутствуют важные функции? Делают ли языковые особенности язык более легким в использовании или трудным для изучения?

Пожалуйста: Нет ответов типа "Язык A лучше, чем язык B, потому что...".

13 ответов

Решение

Да, это риск - и это много обсуждается. Наступает момент, когда очень трудно освоить C# с нуля. К счастью, ситуация немного стабилизировалась, и языковые изменения между C# 3.0 и C# 4.0 относительно незначительны.

На самом деле, я недавно проделал большую работу, пытаясь исправить проблему с обобщением CF, и как часть этого исправления может случиться так, что код возвращается почти к методам C# 1.2 (нет или очень мало обобщений). Таким образом, большинство проблем можно решить с помощью более простых языковых конструкций. Суть в том, как трудно это сделать?

Например - анонимные методы добавляют ОЧЕНЬ много преимуществ для относительно небольшой сложности. dynamic (4.0) добавляет еще несколько для сценариев взаимодействия COM. Блоки итераторов неоценимы для кода в стиле LINQ...

Я вижу много вопросов о нетривиальных частях C#, и я думаю, что мне будет трудно научить новичка всему C# с нуля. Такие книги, как Jon's C# in Depth, хороши для людей, которые уже знакомы с основами (по крайней мере, C# 1.2; в идеале немного C# 2.0), но на самом деле они не предназначены для новичков (я знаю, что Джон не согласится).

Действительно хитрый. К счастью, команда C# установила планку (для включения) очень высоко; что-то новое должно быть очень полезно, чтобы сделать это на языке.

На мой взгляд, C# не имеет слишком много возможностей. Практически любая из новых модных функций 2.0 и 3.0 полезна мне и моим коллегам каждый день, и даже парень из VB быстро подобрал их. Некоторые из новых функций делают изучение языка еще проще, например, использование встроенных лямбд вместо делегатов и ключевых слов var и инициализаторов объектов, и это лишь некоторые из имен C# 3.0 (в C# 3.5, кстати, вы путаетесь что с.NET 3.5).

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

И, по большому количеству функций, C# далек от C++, особенно если вы включите C++0x в эту картинку, что облегчает изучение, несмотря на то, что у некоторых людей "слишком много функций". Моя точка зрения на C++ заключалась в том, что в C# на самом деле не так много возможностей, если хотите.

Когда я пишу код на C#, я использую практически все его возможности. Не все сразу, но каждая функция C# имеет свое место. Многие люди не знают, что в C# есть оператор "::", и никогда не слышали о " внешнем псевдониме", но мне пришлось использовать его сегодня, чтобы разрешить конфликт имен между двумя DLL.

"Доходность" - одна из моих любимых функций. Я не использую его каждый день, но я обычно писал интерфейсы IEnumerator вручную в C# 1.0, и это было огромной болью, которую я бы не хотел повторять. Кроме того, это действительно полезно для написания сопрограмм, даже сопрограмм, которые не производят никакого вывода (yield return null = приостановить операцию).

C# имеет внутренние функции и замыкания. Когда я пишу код на C++, их очень не хватает.

Кажется глупым, что C# имеет так много разных способов написания внутренней функции,

  1. delegate(int x) { return x*x; }
  2. x => x*x
  3. (int x) => { return x*x; }

Но № 1 только по историческим причинам, и формы 2 и 3 каждая имеют свое место.

Будь то методы расширения, перегрузка операторов, обобщенные элементы, общие ограничения, параметры по умолчанию, объединение нулей, троичный оператор, статические конструкторы, проверенные / непроверенные, авто-свойства, директивы препроцессора, типы значений... как программист на полный рабочий день, я использую все хотя бы изредка, и устранение любой из этих функций либо создает для меня дополнительную работу и обострение (foo(x) ?? bar(y) сейчас должно быть написано { var temp = foo(x); if (temp == null) temp = bar(y) }) или требует от меня написания более толстого / более медленного кода (например, если вы замените типы значений классами, часть моего кода замедлится, а использование памяти резко увеличится).

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

Уловка делает возможным программистам, которые не работают полный рабочий день, чтобы понять. (что касается тех людей, которые программируют на C# все время и до сих пор не могут выучить язык - ну, уволить их?) Возможно, это помогло бы, если бы Microsoft сделала функции более "Googlable" или, по крайней мере, "F1-способны". Например, когда я ставлю курсор на "??" или "=>" и нажмите F1, я должен получить справочную страницу для этих операторов. Или рассмотрим статические конструкторы: если код говорит "статический конструктор ()" вместо "статический MyClassName()", тогда будет проще найти его в Интернете.

ИМО, большая проблема, чем языковая раздувание - это раздувание фреймворка. Инфраструктура.NET является гигантской: Microsoft неоднократно воплощала одни и те же вещи, каждый раз создавая раздутые, несовершенные проекты: WinForms и WPF, различные способы доступа к базе данных и т. Д.

Вероятно, вам следует прочитать этот пост Эрика Ганнерсона, члена команды по компиляции C# в Microsoft.

Он объясняет, как новые возможности появляются в языке. По сути, они получают "-100 баллов" в начале, "что означает, что это должно оказать значительное положительное влияние на весь пакет, чтобы он мог перейти на язык".

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

Иногда они едва могут понять код, написанный людьми, использующими все новые функции.

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

В чем причина вашей ситуации? Это:

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

Я бы поспорил, что деньги будут смесью вышеперечисленного.

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

Вы упомянули Linq, и я должен признать, что сначала я был немного скептически настроен, поскольку я всегда считал, что SQL является вполне естественным языком для работы с данными, но теперь мне действительно нравится, и я вижу преимущество оценки запросов на время компиляции. Лямбда-выражения всегда хороши, в действительности они могут затруднить чтение кода при чрезмерном использовании, но иногда они действительно упрощают его. Я не большой поклонник ключевого слова 'var', но иногда оно оказывается полезным, и давайте будем честными, если его не использовать при написании Linq, это затруднит чтение кода. Я сам начинающий программист, и я не думаю, что эти концепции трудно выучить. Я также часто использую Java в школе, и я действительно скучаю по некоторым функциям C# (я не говорю, что Java - плохой язык, напротив, в некоторых отношениях я думаю, что он лучше, чем контракты на C#, особенно для академические цели).

Должно ли быть трудно выучить современный язык программирования?

Для: вы в идеале хотите использовать самый мощный язык, который вы можете, который позволяет вам правильно выражать вещи.

Против: вы хотите думать о проблеме, а не о том, как работает язык.

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

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

Есть ли функции, от которых C# должен избавиться?

Я часто использую новые функции, такие как LINQ, методы расширений, var (я только что написал тип, почему я пишу его снова?) И анонимные функции. Я обнаружил, что они могут дать довольно большие преимущества в производительности. Я бы порекомендовал всем, кто еще не разбирался в LINQ, что им нужно некоторое время для изучения Linq-to-Objects, потому что это очень удобно в любой момент, когда вы настроили логику для работы.

Мне не очень нравится специальный синтаксис LINQ, похожий на SQL. Я нахожу это немного раздражающим в середине кода C# - на мой взгляд, это конфликтует с методом объекта, вызывающим стиль синтаксиса. Я был бы счастлив с более распространенным синтаксисом понимания списка, который используется, например, в Python.

Есть ли новые функции, которые нужны C#?

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

Я также хотел бы, чтобы C# заимствовал улучшенный вывод типов F# и, возможно, его кортежи и множественное присваивание. Может быть, я должен просто пойти и использовать F#.

Да, C# имеет много функций, но именно поэтому мы используем его! Любой, начинающий карьеру программиста, должен рассчитывать на карьеру, изучая / изучая новые вещи и сдавая экзамены! Как человек, который любит изучать новые вещи, вот почему мы любим это!

Лично я нахожу лямбда-выражения и методы расширения, например, чрезвычайно полезными. Для создания крупномасштабных распределенных приложений, в которых я хочу разделить данные и логику, я обнаружил, что LINQ не слишком полезен. Но я с нетерпением жду возможности C# 4, такие как дополнительные параметры.

Как упомянул @Alex, я думаю, что изучение того, как правильно использовать функции, является самым сложным аспектом. Хорра для тех из нас, кто был с C# с первых дней!

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

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

Не многие люди будут читать ваши книги.

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

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

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

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

Даже если я обычный пользователь C#; с большим опытом работы в Delphi, C++ и Python; Я могу понять концепцию C# довольно легко. С # это правильно сбалансированный язык, на мой взгляд. Единственное раздражение в том, что я едва мог вспомнить достаточно синтаксиса (особенно связанного с Linq) в своей голове, чтобы производить код с сенсорной скоростью печати, как я могу в Python. Мое предпочтение паскальскому синтаксису также может помешать мне. Тем не менее, с помощью всемогущего Visual Studio.NET Express это совсем не проблема.

Пока они предоставляют такой замечательный инструмент бесплатно, я считаю, что C# с VS.NET - одна из лучших доступных сред программирования.

Именно благодаря этим возможностям мы используем C# и делаем C# "современным". Если бы C# не предлагал классы, например - или многопоточность, кто-нибудь использовал бы это? Сборка - это пример языка, который действительно не имеет особенностей. Глупо легко учиться как язык, но никто не хочет его использовать.

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

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

Да, C# do имеет много функций, и это не мое мнение, это факт, это богатая платформа. Если кто-то захочет поспорить об этом и заявить, что этот язык не обладает множеством функций, пожалуйста, покажите мне язык, который имеет много функций, и объясните, почему он имеет гораздо больше функций, чем C#.

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

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