Отображение времени компиляции в С#
Я часто пишу код С#, который должен использовать магические строки для выражения имен свойств. Все знают проблемы с магическими струнами. Они очень сложны для рефакторинга, у них нет проверки времени компиляции, и часто они приводят к трудноразрешимым проблемам. Однако С#/.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 предоставляет "Компиляция как услугу".