Отойдя от первичных конструкторов
Предварительный просмотр C# 6 для Visual Studio 2013 поддерживал основную функцию конструкторов, которая, как решили специалисты, не войдет в финальную версию. К сожалению, моя команда реализовала более 200 классов с использованием первичных конструкторов.
Сейчас мы ищем самый простой путь для миграции нашего источника. Поскольку это одноразовая вещь, подойдет магическая строка замены регулярного выражения или хакерский парсер.
Прежде чем я потрачу много времени на написание такого зверя, есть ли кто-нибудь, кто уже сделал это или знает лучший способ?
2 ответа
Как я предлагал в комментариях, вы можете использовать версию Roslyn, которая знает о первичных конструкторах, для синтаксического анализа кода в синтаксическом дереве, а затем изменить это синтаксическое дерево, чтобы вместо него использовать "нормальный" конструктор. Заметьте, что вам также нужно поместить все инициализаторы, которые используют параметры первичного конструктора, в новый конструктор.
Я подозреваю, что написание этого кода заняло бы у меня по крайней мере два или три часа, а возможно, и больше, тогда как я мог бы выполнять работу вручную для действительно большого количества классов за то же время. Автоматизация хороша, но иногда самое быстрое решение на самом деле - это делать вещи вручную... даже 200 классов могут быть быстрее, чем вручную, и вы можете точно распараллелить работу между несколькими людьми.
(\{\s*)(\w*\s*?=\s*?\w*\s*?;\s*?)*?(public\s*\w*\s*)(\w*)(\s*?{\s*?get;\s*?\})(\s*?=\s*?\w*;\s*)
\1\2\4\5
Несколько ответов: первый с простым поиском и заменой Regex, который нужно повторить несколько раз:
Регулярное выражение: несколько строк объяснения, а затем фактическая строка регулярного выражения и строка замены:
а. В регулярном выражении вы сначала сопоставляете полную строку того, что ищете (в вашем случае основной конструктор). Нетрудно сделать: поиск фигурных скобок, слово public, затем два слова, знак равенства и т. Д. Каждый найденный в соответствии с этим текст называется Match.
б. Иногда в тексте возможны повторяющиеся последовательности, которые вы ищете. (В вашем случае: параметры определены в строке для каждого). Для этого вы просто помечаете ожидаемую последовательность как Группу, заключая ее в круглые скобки.
с. Затем вы хотите пометить разные части найденного, чтобы вы могли использовать их или заменить в исправленном тексте. Эти части также называются "Группы", на самом деле "Группы захвата". Снова просто окружите части круглыми скобками. В вашем случае вы сохраните первую захваченную группу (фигурную скобку) и имя свойства с его назначением параметру.
д. Вот регулярное выражение:
(\{\s*)(\w*\s*?=\s*?\w*\s*?;\s*?)*?(public\s*\w*\s*)(\w*)(\s*?{\s*?get;\s*?})(\s*?=\s*?\w*;\s*) 1. ( // ---- Capture1 ----- { // code: \{\s*? // explained: curley bracket followed by possible whitespace ) 2. ( - Capture2 - previously corrected text // - possible multiple lines of 'corrected' non-primary-constructors // created during the find-replace process previously, Propname = paramname; // word, equals-sign, word, semicolon // code: \w*\s*?=\s*?\w*\s*?;\s*? // explained: \w - any alphanumeric, \s - any whitespace // * - one or more times, *? - 0 or more times )*? // code: )*? // explained: this group can be repeated zero or more times // in other words it may not be found at all. // These text lines are created during the recursive replacement process... 3. ( // ----Capture 3----- // The first line of a primary constructor: public type // code: public\s*\w*\s* // explained: the word 'public' and then another word (and [whitespace]) ) 4. ( // ----- capture 4 ----- Propname // code: \w@ // explained: any amount of alphanumeric letters ) 5. ( // ---- capture 5 ---- { get; } // code: \s*?{\s*?get;\s*?\} ) 6. ( // ---- capture 6 ---- = propname; code: \s*?=\s*?\w*;\s* explained: by now you should get it.
Строка замены
\1\2\4\6
Это оставляет:
{
[old corrected code]
[new corrected line]
possible remaining lines to be corrected.
Блокнот ++ 10 минут проб и ошибок. Я гарантирую, это не займет у вас больше, чем это.
Visual Studio 2014 рефакторинг. но а. Вы должны установить его на отдельную виртуальную машину или компьютер. MS предупреждает вас не устанавливать его рядом с существующим кодом. б. Я не уверен, что рефакторинг работает по-другому.
[Here's an article about it][1]
Макросы Visual Studio. Я знаю, я знаю, они давно ушли, но есть по крайней мере два плагина, которые заменяют их и, возможно, больше. Я читал о них в этом обсуждении (Stackru). (Они дают несколько других вариантов) Здесь:
- Visual Commander - бесплатное дополнение для макросов Visual Studio с открытым исходным кодом
VSScript - дополнение Visual Studio: стоит $50!
Попробуйте автоматическое регулярное выражение в качестве примера: вы даете ему несколько примеров кода, в котором вы выделяете то, что является ожидаемым результатом, а затем тот же (или другой) код, в котором вы выделяете то, что НЕ является ожидаемым результатом. Затем вы ждете, пока он пройдет через примеры, и дадите вам некоторый код регулярного выражения.
// для следующего кода (с http://odetocode.com/blogs/scott/archive/2014/08/14/c-6-0-features-part-ii-primary-constructors.aspx)
public struct Money (строковая валюта, десятичная сумма) { public string Currency { get; } = валюта; общедоступная десятичная сумма {get; } = сумма; } // Я получаю что-то вроде: { ++\w\w[^ru][^_]++|[^{]++(?={ \ W ++ =)
Играйте с регулярным выражением на этом замечательном сайте: https://www.regex101.com/
// I first tried: \{\s*((public\s*\w*\s*)\w*(\s*?{\s*?get;\s*?})\s*?=\s*?\w*;\s*)*\}
Повторяющаяся последовательность строк первичного конструктора ("группа повторного захвата") захватывает только последнюю.
- Используйте код C# с
regex.captures
как объяснено здесь в другом Stackru (см. принятый ответ)