Идея для расширения синтаксиса C #

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

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

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

Пожалуйста, дайте мне знать, что вы думаете об этой идее. Возможно ли это, и если да, может ли кто-нибудь направить меня к некоторым полезным руководствам, чтобы добиться этого? В частности, нажатие на событие сборки. Я искал MSDN, но тема (http://msdn.microsoft.com/en-us/library/hthab0h8.aspx) мне не помогла.


person JBSnorro    schedule 20.10.2010    source источник
comment
Это плохая идея.   -  person Steven Sudit    schedule 21.10.2010
comment
Любопытно, у вас есть пример того, какой синтаксис вы бы определили? При создании своего рода предметно-ориентированного языка на C # я обычно пишу тонны методов расширения и использую старый добрый лямбда-синтаксис, чтобы связать элементы моего языка вместе, чтобы сформировать в коде последовательные структуры, подобные предложениям.   -  person David    schedule 21.10.2010
comment
@ Стивен: Хотя я в целом согласен, нужно помнить, что, если бы некий датчанин думал так 30 лет назад, предок C # никогда бы не был изобретен. :)   -  person sbi    schedule 21.10.2010
comment
@sbi: Я подозреваю, что JBSnorro - это не Бьярн Страуструп.   -  person Steven Sudit    schedule 21.10.2010
comment
Так был сделан Ratfor, предшественник C. Я использовал компиляторы FORTRAN 77, которые были компиляторами C с f2c в качестве подготовительного шага. Для этого есть прецеденты.   -  person David Thornley    schedule 21.10.2010
comment
Я почти уверен, что Spec # сделал (или, по крайней мере, мог сделать) именно это. Переведите файлы specs # в простой C #, который затем скомпилируйте.   -  person CodesInChaos    schedule 21.10.2010
comment
@ Дэвид: Например, я мог бы определить $ Меня зовут $ Name и мне $ Age лет. быть равным StringBuilder (Меня зовут) .Append (Name.ToString ()). Append (и я) .Append (Age.ToString ()). Append (лет.). ToString () И я конечно, есть еще много полезных приложений, которые я не могу придумать прямо сейчас. И @ Steven: Я думаю, что расширение языка - хорошая идея (хотя, возможно, и не так). Если расширение языка не является хорошей идеей, почему существуют C # 2.0, C # 3.0, C # 3.5 и C # 4.0?   -  person JBSnorro    schedule 21.10.2010
comment
@JBSnorro: Мне до сих пор снятся кошмары о том, что люди делали с макросами C ++.   -  person    schedule 21.10.2010
comment
Я имею в виду, что это здорово, что C # расширяется, но это не та сила, которая принадлежит среднему разработчику.   -  person    schedule 21.10.2010
comment
@ Стивен: Ты прав, и поэтому я сказал, что в целом согласен с твоим мнением. (Это немного похоже на перегрузку операторов в C ++: вы не должны злоупотреблять операторами для выполнения вещей, которые не очевидны. Но это именно то, что было сделано с операторами сдвига для потоковой передачи и добавления для строк ...)   -  person sbi    schedule 21.10.2010
comment
@JBSnorro: Вы ведь знаете, что могли бы сделать string.Format("My name is {0} and I am {1} years old.", Name, Age), не так ли?   -  person sbi    schedule 21.10.2010
comment
@ Стивен: lol ... Я пытаюсь представить исследовательский S.O. Бьярна. вопрос сейчас: P   -  person Andrew Barber    schedule 21.10.2010
comment
Хорошо, у моего примера могло быть другое тривиальное решение ... хорошо ... Но я до сих пор не понимаю, почему вы бы выступили против этой идеи, если бы у меня был какой-то синтаксис, который действительно мог бы сгладить кодирование   -  person JBSnorro    schedule 21.10.2010
comment
@sbi: Или определите расширение строки, чтобы разрешить "Replace this: {0}".FormatWith(42).   -  person Steven Sudit    schedule 21.10.2010
comment
Я бы предположил, что предоставление собственного синтаксиса в подавляющем большинстве случаев было бы неправильным решением. Однако это все еще очень интересная идея.   -  person Josh Smeaton    schedule 21.10.2010
comment
Хорошо, подведем итоги: в целом идея плохая, если только какой-то синтаксис не является реальным улучшением, которое бывает редко / сложно. Но, по крайней мере, я узнал, что это возможно, вопреки моему предыдущему пониманию.   -  person JBSnorro    schedule 21.10.2010


Ответы (3)


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

Лично я хотел бы прояснить это, сначала отказавшись от идеи, что вы «расширяете» язык C #; Вместо этого я бы подумал об этом как об определении нового языка, синтаксически похожего на C # (я полагаю). Используйте другое расширение файла, чтобы Visual Studio не пыталась скомпилировать ваш язык как C #. (Может быть .csx? Людям нравится добавлять букву x, верно?)

Visual Studio уже делает подобные вещи другими способами, которые могут быть не столь очевидны. Если вы добавляете файл ресурсов в проект, Visual Studio обычно также включает динамически сгенерированный «designer.cs» с кодом, созданным на основе содержимого вашего RESX-файла. Если вы посмотрите на свойства файла .resx, вы заметите, что свойство «Custom Tool» имеет значение ResXFileCodeGenerator. Теоретически вы должны иметь возможность реализовать свой собственный генератор для выполнения упомянутого вами шага перевода. На самом деле, этот перевод не обязательно должен быть разовым, как вы сказали. В процессе перевода должен быть создан новый файл, но исходный файл оставлен без изменений. Любые изменения в исходном файле заставляют Visual Studio регенерировать автоматически созданный файл.

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

Ваш файл .csproj будет содержать что-то вроде следующего:

<Content Include="Example.csx">
  <Generator>ExtendedCSharpCodeGenerator</Generator>
  <LastGenOutput>Example.cs</LastGenOutput>
</Content>
<Compile Include="Example.cs">
  <AutoGen>True</AutoGen>
  <DesignTime>True</DesignTime>
  <DependentUpon>Example.csx</DependentUpon>
</Compile>

Где Example.csx - это файл исходного кода, содержащий ваш расширенный синтаксис, а Example.cs - это результат преобразования Example.csx в обычный код C #.

person Dr. Wily's Apprentice    schedule 20.10.2010
comment
Отлично, это именно то, что я искал сегодня, в частности, динамически сгенерированные node -cs в обозревателе решений. Спасибо. Надеюсь, ссылки, которые вы предоставили, приведут меня туда: P - person JBSnorro; 21.10.2010
comment
Ага! Вот почему я люблю stackoverflow. :) Именно то, что я искал. +1! - person Robin Maben; 22.11.2010

То, о чем вы говорите, кажется идеальной задачей для шаблонов T4 в Visual Studio.

http://msdn.microsoft.com/en-us/library/bb126445.aspx

Вы можете определить все, что захотите; текстовые файлы определенного формата, модели UML, базы данных; и ваш шаблон T4 может преобразовать его в код любым способом, которым вы пожелаете.

person Andrew Barber    schedule 20.10.2010
comment
Да, я уже изучал это, но мне это показалось неудобным, поскольку он может создавать только целые документы, в то время как я предпочитаю «в основном обычный» документ cs с иногда некоторым отклоняющимся синтаксисом. - person JBSnorro; 21.10.2010
comment
Ваше понимание того, как это работает, не совсем правильное. Его также можно использовать для редактирования существующего исходного кода. Например, в шаблоне ASP.NET MVC Contrib T4 для существующих классов Controller был изменен их базовый класс, а их методы изменены на Virtual, чтобы унаследовать сгенерированный код. - person Andrew Barber; 21.10.2010

Не уверен, что это хорошая идея, но у меня просто возникла идея: может быть, вы можете взглянуть на Расширение Visual Studio, загрузите SDK и проверьте документ. Может быть, удастся сделать то, чего вы пытаетесь достичь.

person Sauleil    schedule 20.10.2010