Отображение времени компиляции в С#

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

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

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

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

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

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

Ответ 1

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

Ответ 2

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

Ссылка на примечания к дизайну

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

Ответ 3

У меня была аналогичная проблема. Только недавно обнаружили, что .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);
}

Ответ 4

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

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

Во-вторых: во многих случаях, когда используются магические строки, ReSharper способен распознавать ошибки. Это может помочь совсем немного.

Наконец: то, что вы просите, может быть возможно через компилятор Roslyn, который promises предоставляет "Компиляция как услугу".