пятница, 25 января 2013 г.

Полезные мелочи #1

Недавно мне понадобилось проверить результат компиляции (есть ли ошибки-предупреждения и какие) простого и небольшого фрагмента C# кода будующим компилятором - Microsoft® “Roslyn”.

Отыскать минимальный пример необходимого кода для этого оказалось не сложно: Kirill Osenkov снабдил нас прекрасной инструкцией Introducing the Microsoft “Roslyn” CTP. Получилось, что сделать это можно так вот:

var compilation = Compilation.Create(… ;
EmitResult result;
using(var stream = new MemoryStream()) {
  result = compilation.Emit(stream);
}//using
// Как-то используем result…

Здесь рассматривается только момент, собственно, компиляции, получения результатов и передачи результатов дальше для какой-то обработки. Полностью пример находится тут.

EmitResult содержит результат компиляции (флаг "успешно"/"не успешно") и набор диагностический сообщений (предупреждений и ошибок компиляции). Сама получившаяся сборка (которая "сохранена" в переменной stream) мне не нужна.

Так же, Кирилл поделился ссылкой на compilify.net:

…an interactive web interface for the .NET compiler powered by the Roslyn Project.

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

Мне кажется, это очень неэкономное расходование памяти - понаписать в неё что-то (а компилируемый код может быть и большим) и совершенно не пользоваться записанным результатом. Как раз для таких сценариев, когда некое API требует от вас Stream для записи в него, а вам не нужен будет результат записи или для чтения из него, а вам нечего предоставить, имеется Stream.Null.

Сравните пример кода выше с новой редакцией:

var compilation = Compilation.Create(… ;
var result = compilation.Emit(Stream.Null);
// Как-то используем result…

Мне кажется, стало намного лучше: одна строчка вместо четырёх на получение result и нет лишнего расхода памяти. Полностью пример, для комплексной оценки :о) тут.