Roslyn - это новая платформа компилятора. Он используется только во время компиляции.
Пауло Моргадо
2
@PauloMorgado, это неправда, вы можете использовать Rosyln во время выполнения, чтобы что-то делать. Например, создание живого редактора кода или использование синтаксического анализа Rosyln для работы с деревьями или выражениями или что-то в этом роде
Крис Марисик
@ChrisMarisic, это мое впечатление, но я не ответил, так как мои знания по теме ограничены (отсюда и мой вопрос). Я наткнулся на это: scriptcs.net, который является довольно хорошим примером мощи Roslyn и который, как мне кажется, работает во время выполнения, но я могу ошибаться, поскольку я не очень хорошо осведомлен об этом.
Gigi
@ChrisMarisic, итак, вы говорите, что вы можете использовать Roslyn для создания живого кода из исходного кода, а не из одного исполняемого файла. И вы все еще используете Roslyn для преобразования исходного кода в двоичные файлы, которые не будут использовать Roslyn для изменения этих двоичных файлов. Если вы не можете полностью использовать Roslyn во время выполнения, вы никогда не сможете скомпилировать какой-либо код.
Пауло Моргадо
Ответы:
119
Да. nameof()оценивается во время компиляции. Глядя на последнюю версию спецификаций:
Выражение nameof является константой. Во всех случаях nameof (...) вычисляется во время компиляции для создания строки. Его аргумент не оценивается во время выполнения и считается недостижимым кодом (однако он не выдает предупреждения о «недостижимом коде»).
Как было упомянуто в комментариях, это означает, что при использовании nameofпараметров типа в универсальном типе не ожидайте, что вы получите имя фактического динамического типа, используемого в качестве параметра типа, а не только имя параметра типа. Итак, это:
Предположим, я хочу вывести имя переменной в консоли с помощью nameofоператора:
var firstname ="Gigi";var varname = nameof(firstname);Console.WriteLine(varname);// Prints "firstname" to the console
Когда вы проверяете сгенерированный MSIL, вы увидите, что он эквивалентен объявлению строки, потому что ссылка на объект на строку помещается в стек с помощью ldstrоператора:
Вы заметите, что объявление строки имени и использование nameofоператора генерирует тот же код в MSIL, что означает, что nameofон так же эффективен, как объявление строковой переменной.
Если MSIL декомпилирован в исходный код, насколько легко будет декомпилятору распознать, что это был nameofоператор, а не простая жестко закодированная строка?
ADTC
11
Это хороший вопрос! вы можете опубликовать его как новый вопрос по SO, если хотите получить подробное объяснение :) .. однако короткий ответ заключается в том, что декомпилятор не сможет определить, что это был оператор nameof, а вместо этого будет использовать строковый литерал , Я подтвердил, что это относится к ILSpy и Reflector.
Фарис Засина
2
@ADTC: Поскольку nameof полностью заменяется на load-a-string-on-the-stack, как может декомпилятор даже попытаться угадать, что это nameof, а не простой постоянный параметр?
quetzalcoatl
2
Это интересно. Возможно, декомпилятор сможет проверить строку на соответствие текущему контексту (имя метода / свойства / и т. Д., В котором вы находитесь). Тем не менее, он не может быть на 100% надежным - возможно, вы все-таки использовали жестко запрограммированную строку.
Gigi
2
Хотя я согласен с тем, что вы не можете узнать, является ли это nameof после компиляции, я еще не вижу никаких признаков того, что ILSpy или Reflector поддерживают C # 6. Если это так, вы не можете проверить это @TheMinister
Ответы:
Да.
nameof()
оценивается во время компиляции. Глядя на последнюю версию спецификаций:От имени оператора - v5
Вы можете увидеть это на примере TryRoslyn, где это:
Скомпилировано и декомпилировано в это:
Его эквивалент во время выполнения:
Как было упомянуто в комментариях, это означает, что при использовании
nameof
параметров типа в универсальном типе не ожидайте, что вы получите имя фактического динамического типа, используемого в качестве параметра типа, а не только имя параметра типа. Итак, это:Станет таким:
источник
Я хотел обогатить ответ, предоставленный @ I3arnon, доказательством того, что он оценивается во время компиляции.
Предположим, я хочу вывести имя переменной в консоли с помощью
nameof
оператора:Когда вы проверяете сгенерированный MSIL, вы увидите, что он эквивалентен объявлению строки, потому что ссылка на объект на строку помещается в стек с помощью
ldstr
оператора:Вы заметите, что объявление строки имени и использование
nameof
оператора генерирует тот же код в MSIL, что означает, чтоnameof
он так же эффективен, как объявление строковой переменной.источник
nameof
оператор, а не простая жестко закодированная строка?