次の方法で共有


Почему в C# нет «верхнеуровневых» методов?

C# требует, чтобы каждый метод был в каком-то классе, даже если это статический метод статического класса в глобальном пространстве имён. В других языках разрешены функции «верхнего уровня». Недавно на stackoverflow спросили, почему это так.

Меня всё время спрашивают «почему в C# не реализована возможность X?» Ответ всегда один и тот же: потому что пока что никто не спроектировал, не специфицировал, не реализовал, не протестировал, не задокументировал и не выпустил её. Все шесть компонентов необходимы для того, чтобы возможность появилась. Все они стоят огромных объемов времени, усилий и денег. Возможности недёшевы, и мы очень сильно стараемся обеспечивать выпуск только тех возможностей, которые дают наилучшие преимущества нашим пользователям с учетом наших бюджетов, ограниченных по времени, усилиям, и финансам.

Я понимаю, что такой общий ответ, вероятно, плохо подходит к конкретному вопросу.

В этом частном случае, явные пользовательские преимущества ранее не были достаточно велики, чтобы скомпенсировать усложнение языка. Ограничивая то, как различные элементы языка могут вкладываться друг в друга, мы (1) ограничиваем разрешённые программы общим, лёгким в понимании стилем, и (2) получаем возможность определить такие правила «поиска идентификаторов», которые можно понять, специфицировать, реализовать, протестировать и задокументировать.

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

Теперь, в JScript.NET есть такая возможность. (На самом деле, JScript.NET заходит еще дальше; вы можете размещать на «верхнем уровне» и операторы программы тоже). Напрашивается вопрос: «почему эта возможность хороша для JScript.NET, но плоха для C#?»

В первую очередь, я отказываюсь от предпосылки что эта возможность «плоха» для C#. Она вполне могла бы быть хорошей для C#, просто недостаточно хорошей по сравнению с её себестоимостью (и сравнительной стоимостью реализации этой возможности вместо более ценной возможности). Эта возможность может стать достаточно хорошей для C#, если её стоимость снизится, или неотразимая привлекательность для пользователей вырастет.

Во-вторых, вопрос предполагает, что возможность хороша для JScript.NET. Почему она хороша для JScript.NET?

Она хороша для JScript.NET потому, что JScript.NET разрабатывался и как «скриптовый» язык, и как язык «крупномасштабной разработки». Оргинальный дизайн «классического JScript» как скриптового языка требует, чтобы «однострочная программа и вправду была одной строкой». Если вы намереваетесь сделать язык, обеспечивающий разработчикам-новичкам быструю разработку коротких, простых скриптов, то вы захотите минимизировать объем «ритуальных приплясываний», которые должны выполняться в каждой программе. В JScript вы не хотите быть обязанными начинать с пачки операторов using, определять класс, потом писать всякое внутри класса, иметь функцию Main и т.д. и.т.п, и всё это шаманство просто для того, чтобы получить Hello World.

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

Это меняется. «REPL» - языки типа F#, давно популярные в академических кругах, привлекают растущее внимание в промышленности. Снова появился интерес к «скриптовому» программированию приложений при помощи инструментов вроде like Visual Studio Tools for Applications. Это заставляет нас пересмотреть вопрос о том, является ли «однострочная программа в одну строку» разумной задачей для гипотетических будущих версий C#. До сих пор это явно не входило в список задач дизайна языка.

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

Таким образом, мы рассматриваем добавление этой возможности в гипотетической будущей версии C#, в целях улучшения поддержки «скриптовых» сценариев и REPL разработки. Когда существование новых мощных инструментов зависит от появления возможностей в языке, это увеличивает языковым возможностям шансы на реализацию.

Update: Дополнительные мысли об аргументах в пользу этого потенциального изменения здесь.