Pull to refresh

Comments 10

Что-то подобное уже читал, кажется на medium.
Вот как это часто бывает, все на пример Hello World. Все вокруг похлопали и забыли, потому что нет описания реального применения.

Здорово, что они наконец задумались над внедрением нормальной кодо-генерации.


На самом деле, достичь сходных результатов (далеко не так изящно) можно было уже довольно давно с помощью того же Roslyn и T4.


Несколько лет назад, в одном WebApi2 проекте, я добавил генерацию класса, который был, по сути, билдером URL всех возможных маршрутов в этом API. Это довольно удобно, когда надо вставить в возвращаемые данные ссылки на другие ресурсы этого API. Можно, конечно, было записывать эти URL в виде строк, но это как-то не очень надежно, да и хотелось поэкспериментировать. В итоге, я добавил t4 файлик, который c помощью Roslyn делал перекомпиляцию некоторых файлов из проекта (например RouteConfig.cs) и прямо во время кодо-генерации, запустив перекомпилированный код, я получал экземпляр HttpConfiguration со всем Routes. После этого создать билдер было уже довольно просто.

Я уже несколько лет использую свой велосипед для связки T4 и Roslyn. Вот недавно собрался и выложил его в nuget и на github. Возможно, кому-нибудь пригодится.
Это просто прекрасно. Имхо это один из важных моментов в статье:
Важнейший аспект генераторов — это не то, что они собой представляют, а то, что позволяют реализовать.

Ключевое что нам тут дают удочку вместо того чтоб «накормить». Для более полного понимания инструмента рекомендую прочитать Source Generators Cookbook (ссылка уже есть в статье, но решил продублировать для тех кто пропустил).

ЗЫ: моя мечта чтоб в будущем нам дали более мощные инструменты. В текущей версии мы теперь можем расширять код только путем самого C# языка (например добавить аттрибут). В будущем хотелось бы иметь возможность писать на своем диалекте C#. К примеру MS планирует добавить в C# 9.0 Records. Вместо этого хотелось бы оставить vanilla C# как можно проще и самому расширять язык добавляя свои data, init и другие keywords в синтаксис языка.
хотелось бы иметь возможность писать на своем диалекте C#

Чтобы стать незаменимым?

В смысле? Типа я один в команде сделал некое расширение в языке для проэкта и теперь меня боятся уволить так как никто другой не может разобраться в этом? Это не так как я это видел :)
Создание такого диалекта это довольно нетривиальная задача и далеко не каждый «сенйор» сделает это грамотно. Я за подход как и с популярными библиотеками — это на строне комьюнити. А команда проэкта лишь решает что следуть им добавить себе: так же как добавляем логгер или сериализатор хотелось чтоб можно было расширить свой код неким паттерн матчингом, рекордами. Вам понравилась фича «Nullable Reference Types»? Как насчет сделать свою подобную имплементацию компайл тайм валидации, но основанную не на null а на чем то большем? (например анализировать call graph на пример того как инициировались входящие в ваш метод аргументы, или что метод был вызван внутри некого «using(new Context())» )
Хорошим примером можно считать specflow: довольно интересный инструмент который легко добавить в проэкт и не сложно разобраться любому опытному программисту. И в тоже время не требует от вас знать как оно работает изнутри и саппортить это. Только минус тут то что Gherkin это отдельный язык который генерирует C# код перед компиляцией.
Еще пример: linq внутри C#. Представьте что есть комьюнити которое развивает свой язык наподобие linq для обработки данных и вам он очень подходит для ваших задач. Идея в том чтоб само комьюнити сделало «plugin» для C# и дало вам возможность использовать его сразу в «удобоваримом» виде и не ждать некого C# версии 20.0 когда сама MS добавит его.

В Nemerle как раз Linq реализован в виде отлётного макро-расширения, и любой может добавить свой синтаксис.

А свой эмиттер IL кода и расширения CLR тоже добавлять? Ну дадут вам возможность расширять язык — компилятор повыбрасывает все ваши расширения т.к. не будет знать что с ними делать. Хотите наибольшей свободы — пишите в IL кодах в них можно много чего написать не ожидая пока MS сделают плагинную систему языка :-)

лучше бы добавили реалтайм код едит в режиме дебага, уже сколько лет обещают....

Это крутая штука, я 2 года назад пытался прикрутить генератор на основе рослина и основной проблемой было как раз «встроиться» в шаги компиляции. В итоге все быглядело не так красиво как хотелось бы.
А вообще я мечтаю чтобы появились «генераторы» как конструкция языка.
Что-то типа макросов. чтобы можно было писать например как-то так:
class A {

bool Equals (A obj2){
<codegen.foreach(var fieldName in buildContext.thisClass.Fields) >
if(this.<codegen fieldName />!= obj2.<codegen fieldName />)
return false;
</codegen.foreach>
return true;
}
}

и на этапе компиляции этот макрос разворачивается.
Sign up to leave a comment.

Articles