Отражение времени компиляции в C # - PullRequest
20 голосов
/ 18 февраля 2012

Я часто пишу код на C #, который должен использовать магические строки для выражения имен свойств. Всем известны проблемы с волшебными струнами. Их очень трудно реорганизовать, у них нет проверки времени компиляции, и часто они приводят к трудным для диагностики проблемам. Тем не менее C # /. NET использует их повсеместно для представления имен свойств / классов / методов.

Эта проблема сохраняется годами и годами, и в настоящее время единственное жизнеспособное решение - использовать дерево выражений, которое затем анализируется во время выполнения для имени свойства. Это дает вам удовлетворительную проверку во время компиляции, но усложняет код (требующий параметров типа Expression), и - это затраты времени выполнения.

Кто-нибудь знает, была ли когда-либо рассмотрена возможность C # / .NET для добавления отражения во время компиляции, чтобы преодолеть эту распространенную проблему?

Кажется, что это было бы простое добавление, это было бы неразрывным изменением, и оно очень помогло бы многим разработчикам. Оператор typeof () уже выполняет форму отражения во время компиляции, поэтому кажется, что оператор nameof () (или что-то подобное) будет очень полезным.

Кроме того, кто-нибудь знает о возможных проблемах с такой функцией?

Спасибо за помощь.

Ответы [ 4 ]

13 голосов
/ 31 января 2015

В C # 6.0 добавляется новый оператор nameof, который позволит вам получать имена свойств, классов, полей, событий и переменных во время компиляции.

Ссылка на проектные заметки

Больше не нужно размышлять над информацией, которую компилятор уже знает во время разработки!

13 голосов
/ 18 февраля 2012

Прямо из источника - это сообщение в блоге дизайнера языка C #, и «Пользователь» в этом посте задает те же вопросы, что и вы, и на него дан ответ.Автор говорит, что необходимо будет указать синтаксис для каждого элемента метаданных, который вы хотите запросить, и это не тривиально - т.е.какую перегрузку вы хотите, если вам нужен метод "info-of" и метод перегружен?Что, если задействованы дженерики и явные реализации интерфейса?И так далее.Оказывается, хотя это не считалось достойным реализации в 2009 году по этим причинам, мы получим его в C # 6 в 2015 году - см. Примечания по проектированию языка C # от 9 июля 2014 года .

6 голосов
/ 29 января 2015

У меня была похожая проблема.Только недавно обнаружилось, что .NET Framework 4.5 имеет функцию, называемую Caller Info атрибутами.Используя их, вы можете получить информацию о вызывающей стороне метода во время компиляции.Вы можете получить путь к файлу исходного кода, номер строки в исходном коде и имя члена вызывающей стороны.

public void DoProcessing()
{
    TraceMessage("Something happened.");
}

public void TraceMessage(string message,
        [CallerMemberName] string memberName = "",
        [CallerFilePath] string sourceFilePath = "",
        [CallerLineNumber] int sourceLineNumber = 0)
{
    Trace.WriteLine("message: " + message);
    Trace.WriteLine("member name: " + memberName);
    Trace.WriteLine("source file path: " + sourceFilePath);
    Trace.WriteLine("source line number: " + sourceLineNumber);
}
0 голосов
/ 18 февраля 2012

Тем не менее C # / .NET использует их повсеместно для представления имен свойств / классов / методов.

Во-первых, я не согласен.Существуют определенные фреймворки (например, WebForms), которые повсеместно используют магические строки, но базовые библиотеки для C # и .NET имеют тенденцию избегать таких вещей на удивление хорошо.ReSharper может распознавать ошибки.Это может немного помочь.

Наконец: то, о чем вы просите, может быть реализовано с помощью компилятора Roslyn, который обещает предоставить «Компиляция как сервис».

...