Visual studio это case средство или нет

Обновлено: 06.07.2024

Позволяет выбирать между несколькими разделами кода в зависимости от значения целочисленного выражения.

Синтаксис

selection-statement :
switch ( init-statement opt C++ 17 condition ) statement

labeled-statement :
case constant-expression : statement
default : statement

Примечания

Оператор switch передает управление одному из labeled-statement в своем теле в зависимости от значения condition .

Объект condition должен иметь целочисленный тип или быть типом класса с однозначным преобразованием в целочисленный тип. Целочисленное повышение выполняется, как описано в разделе стандартные преобразования.

switch Текст инструкции состоит из ряда case меток и opt default метки ионал. Является labeled-statement одной из этих меток и инструкциями, приведенными ниже. Помеченные операторы не являются синтаксическими требованиями, но switch оператор не имеет смысла без них. Ни одно constant-expression из двух значений в case операторах не может иметь одно и то же значение. default Метка может отображаться только один раз. default Оператор часто помещается в конец, но может находиться в любом месте switch тела инструкции. Метка case или default может располагаться только внутри оператора switch .

constant-expression В каждой case метке преобразуется в постоянное значение, которое имеет тот же тип, что и condition . Затем он сравнивается с condition для равенства. Управление передается первой инструкции после case constant-expression значения, совпадающего со значением condition . Поведение, полученное в результате, показано в следующей таблице.

switch поведение инструкции

Условие Действие
Преобразованное значение соответствует значению выражения управления с повышенным уровнем. Управление передается оператору, следующему за этой меткой.
Ни одна из констант не соответствует константам в case метках; default имеется метка. Элемент управления передается в default метку.
Ни одна из констант не соответствует константам в case метках; default Метка отсутствует. Элемент управления передается оператору после switch оператора.

Если найдено совпадающее выражение, выполнение можно продолжить через более поздние case или default метки. break Оператор используется для того, чтобы прерывать выполнение и передавать управление оператору после switch инструкции. Без break оператора выполняется выполнение всех инструкций из соответствующей case метки в конец switch , включая default . Пример:

В приведенном выше примере uppercase_A увеличивается, если c является верхним case 'A' . break Инструкция после uppercase_A++ завершает выполнение switch тела оператора и управление передается в while цикл. Без break оператора выполнение перейдет к следующему оператору с меткой, так что lowercase_a и other будет также увеличен. Аналогичное назначение обрабатывается break оператором для case 'a' . Если значение меньше c case 'a' , lowercase_a то увеличивается и break оператор завершает switch тело оператора. Если c не является 'a' или 'A' , default выполняется инструкция.

Visual Studio 2017 и более поздних версий: (доступно с /std: c++ 17) [[fallthrough]] атрибут указан в стандарте c++ 17. Его можно использовать в switch операторе. Это подсказка для компилятора или любой, кто читает код, это пошаговое поведение является намеренным. Компилятор Microsoft C++ в настоящее время не предупреждает о поведении fallthrough, поэтому этот атрибут не влияет на поведение компилятора. В этом примере атрибут применяется к пустой инструкции в незавершенном операторе с меткой. Иными словами, необходимо поставить точку с запятой.

Visual Studio 2017 версии 15,3 и более поздних версий (доступно в /std: c++ 17). switch Оператор может содержать init-statement предложение, которое заканчивается точкой с запятой. Он вводит и инициализирует переменную, область которой ограничена блоком switch оператора:

Внутренний блок switch инструкции может содержать определения с инициализаторами, если они достижимы, то есть не обходятся всеми возможными путями выполнения. Имена, добавленные с помощью этих объявлений, имеют локальную область видимости. Пример:

switch Оператор может быть вложенным. При вложении case метки или default связываются с ближайшим switch оператором, в котором они заключены.

Поведение в системах Майкрософт

Microsoft C++ не ограничивает количество case значений в switch операторе. Это число ограничивается только объемом доступной памяти.

Порою кажется, что все вокруг устроено несложно: солнце светит, лампочки мигают, зарплату выдают вовремя. Но только захочешь сделать что-нибудь "полезное для общества", приглядишься повнимательнее, и сразу все становится ой как не просто - на пути встают комплексные объекты и системы: жилищно-коммунальное хозяйство, экономический кризис, вертикаль власти, топология, логистика территориально распределенных сетей, уголовно-процессуальный кодекс, методология планирования ресурсов с учетом производственных ограничений.

Когда в одну кучу собирается несколько разнородных объектов с различными свойствами и взаимосвязями, которые не удерживаются в одной голове в один момент времени, у человека возникает естественная когнитивная потребность "наклеить ярлычки, разложить все по полочкам, а полочки разместить по шкафчикам".

CASE’оведы и CASE’олюбы

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

"Свято место пусто не бывает": раз есть потребность, то есть и предложение. Вот уже более 30 лет развиваются многообразные CASE-средства - средства компьютеризированного анализа, проектирования, перепроектирования, контроля за соблюдением соответствия тому, что было спроектировано и т. п.

Некоторых российских представителей фирм - поставщиков этих средств мы недавно собрали за круглым столом, чтобы вместе разобраться в спектре многообразных возможностей систем указанного класса (тоже, кстати, непростых).

Широкий спектр CASE-инструментария, охватывающего разнообразную деятельность - от анализа бизнес-структур и бизнес-требований до поддержки жизненного цикла разработки и сопровождения информационных систем, - не кажется искусственным в свете неразрывной связи систем управления организациями и ИС. Не случайно буква S в термине CASE (Computer Aided S. Engineering) трактуется сегодня в широком смысле: и как Software, и как System (хотя изначально было software), ведь программные продукты - это частный (специализированный) случай систем вообще.

Попробуем разобраться, какой длины жизненный цикл и жизненный цикл чего и для кого могут поддерживать рассматриваемые в этом обзоре CASE-инструменты.

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

Используемые в CASE-средствах модели (визуальная составляющая CASE-инструментов) - это общий язык для всех участников некоего процесса, обеспечивающий возможность задавать те или иные аспекты предметной области с помощью общей терминологии, общих графических изображений (нотаций). Модели являются предметом коммуникаций, без которых не о чем говорить, нечего обсуждать, так как предмет не определен. Но кроме предмета коллективной разработки нужны также и специальные средства коллективизации усилий, пространство, в котором должны согласованно действовать все участники в рамках общего проекта.

Михаил Кумсков: "Наша практика показывает, что инструмент по отношению к процессам жизненного цикла вторичен. И мы, начиная внедрение, в первую очередь уделяем внимание управлению требованиями, управлению изменениями, ставим эти процессы. А потом уже учим участников пользоваться средствами визуального моделирования, анализа, проектирования и т. д. Потому что изначально должна быть налажена прозрачность коммуникаций и управляемость коллективом через специализированные средства ее поддержки".

С учетом многообразия проектов, протекающих в организациях, хотелось бы расширить понятия CASE до средств поддержки взаимодействия бизнес - ПО - бизнес, объединить их в единое целое, ведь программные продукты затем и нужны, чтобы управлять и помогать в управлении бизнесом. Дело в том, что задачи проектирования ИС и задачи оптимизации бизнес-процессов (или бизнеса как такового) переплетаются очень тесно. Более того, оптимизация бизнеса без внедрения ИС сейчас в принципе невозможна. Поэтому все должно быть связано методологически, а еще лучше - технологически (это может быть единая CASE-система, может быть несколько бесшовно интегрированных CASE-инструментов,).

Антон Шматалюк: "Наше понимание жизненного цикла максимально широко: CASE-средства сначала являются инструментом для бизнеса, затем они используются в качестве мостика между бизнесом и проектировщиками информационных систем, далее - как средства проектирования и создания ИС, и, наконец, они осуществляют обратную связь, отслеживая эффективность взаимодействия готовой ИС с бизнесом.

При внедрении информационной системы в организации должны поддерживаться как бизнес-процессы, заложенные в самой ИС, так и смежные неавтоматизированные процессы организации. Без этого полноценного внедрения не получится. Ведь организация действует в единой системе, все процессы тесно взаимосвязаны, и только в совокупности они обеспечивают целостность деятельности компании, где всеми процессами нужно управлять и регулярно их оптимизировать".

Большинство поставщиков имеют несколько другой взгляд на определение области применения CASE: одни инструменты и модели предназначены для разработчиков информационных систем, другие - организационным аналитикам, но авторы все же считают, что постепенно эти две линии сойдутся "у ног клиента".

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

Сегодня важны не только удобство и скорость работы в той или иной среде разработки (что на протяжении значительной, более чем 20-летней истории нашей компании было в центре внимания). На первый план выходят аспекты обеспечения качества создаваемых программных продуктов, степень их документированности (как с точки зрения пользователей, так и ИТ-специалистов и разработчиков), легкость сопровождения и, конечно, возможность расширения их функциональности в соответствии с запросами пользователей".

Среди CASE-средств для разработчиков сейчас наиболее популярны средства проектирования баз данных (БД). Поскольку структура БД, создаваемой ИС, как правило, весьма сложна, то ее разработка - процесс трудоемкий. К тому же необходимо обеспечить связь между модельной составляющей и БД, автоматическое написание рабочего кода приложения, существенно экономящее время программистов и гарантирующее проектировщикам, что в системе воплощено именно то, что они задумали.

Не так давно начали пользоваться популярностью CASE-средства, предназначенные для проектирования архитектуры ИС, т. е. для так называемых системных архитекторов, отвечающих за модульное построение, интерфейсы, соединение в единое целое разнородных клиент-серверных приложений в рамках проекта.

Если целью работы с CASE-средствами является программный продукт, то он, как правило, создается на некотором языке программирования в определенной среде разработки. Такие возможности CASE-средств, как автоматическое создание кода и обратный процесс - построение диаграмм на основании исходного кода, методы анализа качества кода, требуют, чтобы осуществляющее их приложение "знало" соответствующий язык и среду программирования на уровне компилятора данного языка.

Тот факт, что некоторые производители CASE-средств попутно являются конкурирующими производителями языков и сред разработки, накладывает свой отпечаток. Так, если вы используете средства разработки от Microsoft, то для вас вряд ли окажутся полезными CASE-средства Oracle. Аналогично не приходится ожидать особой поддержки Oracle и Borland в средствах Microsoft. В то же время продукт IBM Rational Rose имеет кодогенераторы как для языков Microsoft Visual Studio, так и для языка Borland Delphi. Но в целом ориентированность некоторых комплексов CASE-средств на определенные среды разработки может оказаться столь велика, что это способно значительно сузить круг при поиске подходящего инструмента в том случае, когда среда разработки приложения уже выбрана. (В этом смысле приведенная ниже таблица сравнения не вполне корректна и должна рассматриваться читателями с указанной оговоркой.)

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

Перед тем как что-то автоматизировать, организации необходимо описать на стандартизированном CASE-языке модель своего бизнеса, выделить из него часть, подлежащую автоматизации. Утвержденный результат этого процесса и должен быть передан разработчикам автоматизированной системы в качестве технического задания на разработку (ТЗ). К сожалению, эту последовательность действий соблюдает пока очень малое число предприятий, внедряющих у себя ERP-системы, и это одна из главных причин провала проектов внедрения, поскольку ТЗ, написанное на естественном (неформализованном) языке, всегда оставляет огромное поле для недопонимания сторон.

Кроме того, по имеющейся статистике, 80% средств, которые ИT-службы предприятий тратят на программное обеспечение, уходят на сопровождение, а не на разработку (закупку) систем. И можно понять, почему. Высокие затраты на сопровождение, во-первых, связаны с плохим изначальным проектированием систем. CASE-средства способны эти затраты снизить. Во-вторых, в реальной жизни к системе в процессе ее эксплуатации предъявляются новые требования, у бизнеса появляются новые задачи, когда организация развивается. Не могут избежать непрерывных изменений и разработчики - как тиражных систем (вынужденные выводить все новые и новые версии на рынок), так и заказных, постоянно доделывающие что-то в ИС под новые требования заказчика. Так что изменения систем неизбежны, и было бы уместно, если бы CASE-средства поддерживали процессы изменений функционирующих ИС, причем желательно в режиме реального времени (реинжиниринг информационной системы без остановки жизненно важных ее элементов).

Галина Антипина: "Команды, которые профессионально занимаются разработкой информационных систем, постепенно начинают осознавать необходимость комплексного применения средств управления созданием ПО. Раньше они ограничивались средствами моделирования (бизнес-процессов, баз данных, информационных систем). Сейчас все больше компаний понимает необходимость использования таких специализированных продуктов, как средства конфигурационного управления проектами, контроля версий, тестирования. В первую очередь такой интерес идет от руководителей отделов разработки, которые понимают, что использование таких продуктов позволяет сократить время создания, повысить качество ПО, выполнить проекты в заданные сроки и в рамках бюджета. Непосредственные участники проектов (аналитики, разработчики и др.) выигрывают в первую очередь от упрощения коммуникации между участниками проекта, что позволяет значительно сократить время на поиск нужных документов, файлов, "самой последней" версии создаваемой программы и сосредоточиться на выполнении конкретных задач".

Алла Прохорова: "Для реализации полноты всех ступеней жизненного цикла только инструментальных средств мало, нужна методология разработки, задающая правила игры. Причем методология, адаптированная к нуждам конкретной фирмы. Как на предприятиях реального сектора нужны собственные бизнес-технологии ведения их деятельности в виде бизнес-процессов, так и компаниям-разработчикам необходим свой аналогичный каркас. Именно для этих задач и создана методология ведения проектов разработки (Rational Unified Process, RUP). Она представляет собой энциклопедию, в которой описаны роли участников проекта, инструкции. В адаптированном RUP возникают свои роли под свой стиль работ, и уже под нужные процессы делаются инструкции, собственный шаблонированный документооборот проектных документов. Постепенно собирается библиотека моделей, требований, репозитории".

Антон Шматалюк: "После того как информационная система создана, необходимо обучение пользователей, соединение ее с имеющимися в организации процессами. Пренебрежение этим может повлечь еще большие затраты на сопровождение, например из-за того, что система внедрена, но с ней до конца не умеют работать. По результатам эксплуатации нужен анализ использования ИС, управление дальнейшей автоматизацией предприятия, оптимизация на основе анализа. Будущие CASE-средства обязательно должны эти позиции поддерживать. ARIS уже начинает идти по этому пути, предлагая, например, ARIS Redocumentation SCOUT для аудита внедренных систем SAP".

В идеале необходимо, чтобы CASE-линейка обеспечивала с точки зрения менеджмента адекватную связь между всеми средствами поддержки жизненного цикла организационной системы, включая преобразование организационных технологий в корпоративные приложения (например, в виде workflow- или BPM-систем, средств интеграции различных приложений и бизнес-процессов и пр.).

В дальнейших частях обзора мы коснемся модельных, технологических характеристик рассматриваемых CASE-систем, а также анализа деятельности их поставщиков.

Основные этапы жизненного цикла систем, их поддержка, а также значимые свойства представленных линеек продуктов

Выполняет одну из нескольких групп инструкций в зависимости от значения выражения.

Синтаксис

Компоненты

Термин Определение
testexpression Обязательный. Выражение. Необходимо вычислить до одного из простейших типов данных (. Boolean Byte Char Date Double Decimal Integer Long Object SByte Short Single String UInteger ULong и UShort ).
expressionlist Требуется в Case операторе. Список предложений выражений, представляющих значения соответствия для testexpression . Несколько предложений выражений разделяются запятыми. Каждое предложение может принимать одну из следующих форм:

- expression1 To выражение2
-[ Is ] компарисоноператор выражение
- выражение

Используйте To ключевое слово, чтобы указать границы диапазона значений соответствия для testexpression . Значение expression1 должно быть меньше или равно значению expression2 .

Используйте Is ключевое слово с оператором сравнения ( = , <> . < <= > или >= ), чтобы указать ограничение на значения сопоставления для testexpression . Если Is ключевое слово не указано, оно автоматически вставляется перед компарисоноператор.

Форма, указывающая только expression , рассматривается как особый случай формы, Is где компарисоноператор — знак равенства ( = ). Эта форма вычисляется как testexpression = expression .

Комментарии

Если testexpression соответствует любому Case expressionlist предложению, инструкции, следующие за этим Case оператором, выполняются до следующей Case Case Else инструкции, или End Select . Затем управление передается следующему оператору End Select . Если testexpression соответствует expressionlist предложению в более чем одном Case предложении, выполняются только инструкции, следующие за первым совпадением.

Case Else Оператор используется для представления elsestatements для запуска, если между testexpression expressionlist предложением и в других инструкциях не найдено совпадений Case . Хотя это и не является обязательным, рекомендуется иметь Case Else в конструкции оператор, Select Case обрабатывающий непредвиденные testexpression значения. Если Case expressionlist предложение не совпадает testexpression и отсутствует Case Else оператор, управление передается оператору ниже End Select .

В каждом предложении можно использовать несколько выражений или диапазонов Case . Например, следующая строка допустима.

Case 1 To 4, 7 To 9, 11, 13, Is > maxNumber

Is Ключевое слово, используемое в Case Case Else операторах и, не совпадает с оператором is, который используется для сравнения ссылок на объекты.

Можно указать диапазоны и несколько выражений для символьных строк. В следующем примере Case соответствует любой строке, которая равна «яблоки», имеет значение между «гайкями» и «полный курс» в алфавитном порядке или содержит точно то же значение, что и текущее значение testItem .

Параметр Option Compare может влиять на сравнения строк. В Option Compare Text строках «яблоки» и «яблоки» сравниваются как одинаковые, но в противном случае — Option Compare Binary нет.

Case Оператор с несколькими предложениями может демонстрировать поведение, называемое сокращенным вычислением. Visual Basic вычисляет предложения слева направо, и если одно из них создает совпадение с testexpression , оставшиеся предложения не оцениваются. Сокращенное вычисление может повысить производительность, но может привести к непредвиденным результатам, если ожидается вычисление каждого выражения в expressionlist . Дополнительные сведения об сокращенном вычислении см. в разделе логические выражения.

Если код в Case Case Else блоке инструкций или не требует выполнения каких-либо инструкций в блоке, он может выйти из блока с помощью Exit Select инструкции. Это немедленно передает управление оператору, приведенному ниже End Select .

Select Case конструкции могут быть вложенными. Каждая вложенная Select Case конструкция должна иметь соответствующий End Select оператор и должна быть полностью заключена в один Case Case Else блок инструкций или внешней конструкции, Select Case внутри которой он вложен.

Пример

В следующем примере конструкция используется Select Case для записи строки, соответствующей значению переменной number . Вторая Case инструкция содержит значение, совпадающее с текущим значением number , поэтому инструкция, записывающая "между 6 и 8 включительно", выполняется.

В этом руководстве описано, как создать анализатор и соответствующее исправление кода с помощью API Roslyn. Анализатор выполняет анализ исходного кода и сообщает о проблеме пользователю. При необходимости исправление кода можно связать с анализатором, чтобы представить изменения в исходном коде пользователя. В этом руководстве описано, как создать анализатор, ищущий локальные переменные, которые можно объявить с помощью модификатора const , но которые не объявлены. Сопутствующее исправление кода добавляет модификатор const в эти объявления.

Предварительные требования

Инструкции по установке — Visual Studio Installer

Установка с помощью Visual Studio Installer — представление "Рабочие нагрузки"

Кроме того, вы можете настроить редактор DGML для отображения диаграмм в средстве визуализации:

  1. Откройте узел Отдельные компоненты в дереве сводки.
  2. Установите флажок Редактор DGML

Установка с помощью Visual Studio Installer — вкладка "Отдельные компоненты"

Кроме того, вы можете настроить редактор DGML для отображения диаграмм в средстве визуализации:

  1. Установите флажок Редактор DGML. Нужный пакет будет представлен в разделе Средства для работы с кодом.

Создать и проверить анализатор можно несколькими способами:

  1. Создайте решение.
  2. Зарегистрируйте имя и описание анализатора.
  3. Создайте отчет анализатора о предупреждениях и рекомендациях.
  4. Внедрите исправление кода, чтобы принимать рекомендации.
  5. Улучшите анализ с помощью модульных тестов.

Создание решения

Изучение шаблона анализатора

Анализатор с шаблоном исправления кода создает пять проектов:

  • MakeConst — включает анализатор;
  • MakeConst.CodeFixes — включает исправление кода;
  • MakeConst.Package — используется для создания пакета NuGet для анализатора и исправления кода;
  • MakeConst.Test — проект модульного теста;
  • MakeConst.Vsix — проект запуска по умолчанию, который запускает второй экземпляр Visual Studio с загруженным новым анализатором. Нажмите клавишу F5 , чтобы запустить проект VSIX.

Когда вы запустите анализатор, откроется вторая копия Visual Studio. Эта вторая копия использует другой куст реестра для хранения параметров, что позволяет различить параметры визуальных элементов в обоих копиях Visual Studio. Вы можете выбрать другую тему для экспериментального запуска Visual Studio. Кроме того, не следует перемещать параметры или выполнять вход в учетную запись Visual Studio в экспериментальном экземпляре Visual Studio. Так параметры останутся разными.

В состав куста входит не только разрабатываемый анализатор, но и все открытые ранее. Чтобы сбросить куст Roslyn, необходимо вручную удалить его из раздела LocalAppData%\Microsoft\VisualStudio. Имя папки куста Roslyn будет заканчиваться на Roslyn , например 16.0_9ae182f9Roslyn . Обратите внимание, что после удаления куста может потребоваться очистить решение и перестроить его.

Шаблон создает анализатор, который выдает предупреждение на каждое объявление типа, где имя типа состоит из букв нижнего регистра, как показано ниже:

Предупреждение от анализатора

Также шаблон содержит исправление кода, которое меняет любые буквы нижнего регистра в имени типа на буквы верхнего регистра. Предлагаемые исправления можно просмотреть, щелкнув значок лампочки рядом с предупреждением. После принятия изменений имя типа и все ссылки на этот тип будут обновлены. Теперь, когда вы увидели работу начального анализатора, закройте второй экземпляр Visual Studio и вернитесь к проекту анализатора.

Для тестирования изменений в анализаторе не требуется каждый раз запускать вторую копию Visual Studio, так как шаблон создает проект модульного теста. В этом проекте содержатся два теста. TestMethod1 показывает обычный формат теста, при котором анализ кода происходит без активации диагностики. TestMethod2 — формат, при котором сначала активируется диагностика, а затем применяется исправление кода. Во время сборки анализатора и исправления кода вы напишете тесты для проверки разных структур. Модульные тесты проводятся гораздо быстрее, чем интерактивное тестирование анализаторов в Visual Studio.

Модульные тесты анализатора — отличный инструмент, если вы знаете, какие конструкции кода должны и не должны запускать анализатор. В свою очередь запуск анализатора в другой копии Visual Studio позволяет определить и найти конструкции, о которых вы еще не задумывались.

В этом руководстве показано, как написать анализатор, информирующий пользователя о любых объявлениях локальной переменной, которые можно преобразовать в локальные константы. Рассмотрим следующий пример кода:

В приведенном выше коде x присваивается значение константы, которое никогда не меняется. Ее можно объявить с помощью модификатора const :

В файле MakeConstAnalyzer.cs с помощью шаблона создается начальный класс DiagnosticAnalyzer . В этом начальном анализаторе отображены два важных свойства каждого анализатора.

  • В каждом диагностическом анализаторе должен быть указан атрибут [DiagnosticAnalyzer] , который описывает язык, на котором он работает.
  • Каждый диагностический анализатор должен быть производным (прямо или косвенно) от класса DiagnosticAnalyzer.

Также в шаблоне отображены базовые функции любого анализатора:

Действия регистрируются в переопределении метода DiagnosticAnalyzer.Initialize(AnalysisContext). При работе с этим руководстве вы просмотрите синтаксические узлы локальных объявлений и узнаете, какие из них имеют значения констант. Если объявление может быть константой, анализатор создаст диагностику и сформирует отчет.

Сначала обновите константы регистрации и метод Initialize , так как константы определяют ваш анализатор MakeConst. Большинство строковых констант определены в файле строковых ресурсов. Используйте их, чтобы упростить локализацию. Откройте файл Resources.resx для проекта анализатора MakeConst. Откроется редактор ресурсов. Измените строковые ресурсы, как показано ниже:

  • Измените AnalyzerDescription на Variables that are not modified should be made constants. .
  • Измените AnalyzerMessageFormat на Variable '' can be made constant .
  • Измените AnalyzerTitle на Variable can be made constant .

После настройки редактор ресурсов будет выглядеть как на рисунке ниже:

Обновление строковых ресурсов

Замените ее приведенным ниже кодом:

После этого метод AnalyzeSymbol можно удалить. Этот анализатор проверяет SyntaxKind.LocalDeclarationStatement, а не операторы SymbolKind.NamedType. Обратите внимание на то, что AnalyzeNode подчеркивается красной волнистой линией, так как код, который вы только что вставили, ссылается на метод AnalyzeNode , который еще не объявлен. Объявите этот метод, используя приведенный ниже код:

Измените Category на Usage в файле MakeConstAnalyzer.cs, как показано в следующем коде:

Поиск локальных объявлений, которые могут быть константами

Теперь мы напишем первую версию метода AnalyzeNode . Он должен найти одно локальное объявление, которое может быть const , но таковым не является. Пример приведен ниже:

Сначала найдите локальные объявления. Добавьте приведенный ниже код в AnalyzeNode в файле MakeConstAnalyzer.cs:

В конце проверьте, может ли переменная быть const . Это означает, что она не может быть назначена после инициализации.

Выполните семантический анализ с помощью SyntaxNodeAnalysisContext. Используйте аргумент context , чтобы определить, можно ли объявление локальной переменной сделать const . Microsoft.CodeAnalysis.SemanticModel представляет все семантические сведения в одном исходном файле. См. дополнительные сведения о семантических моделях. С помощью Microsoft.CodeAnalysis.SemanticModel выполните анализ потока данных на операторе локального объявления. Затем, используя результаты этого анализа потока данных, убедитесь, что в локальную переменную не записывается новое значение где-либо еще. Вызовите метод расширения GetDeclaredSymbol, чтобы извлечь ILocalSymbol переменной и убедиться, что она не содержится в коллекции DataFlowAnalysis.WrittenOutside из анализа потока данных. Добавьте в конце метода AnalyzeNode приведенный ниже код:

Этот код гарантирует, что переменная не изменена и может быть const . Теперь мы активируем диагностику. Добавьте приведенный ниже код в последнюю строку метода AnalyzeNode :

Чтобы проверить состояние, запустите анализатор, нажав клавишу F5 . Загрузите консольное приложение, созданное ранее, и добавьте приведенный ниже код теста:

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

Написание исправления кода

Анализатор поддерживает одно или несколько исправлений кода. Исправление кода определяет, какие правки нужно внести для решения обнаруженной проблемы. Исправление кода вашего анализатора предоставляет код с ключевым словом const:

Пользователь выбирает исправление в интерфейсе лампочки в редакторе, а Visual Studio изменяет код.

Откройте файл CodeFixResources.resx и измените CodeFixTitle на Make constant .

Откройте файл MakeConstCodeFixProvider.cs, добавленный шаблоном. Это исправление уже привязано к идентификатору диагностики вашего анализатора, но оно пока не реализует преобразование кода.

Затем удалите метод MakeUppercaseAsync . Он больше не применяется.

Затем, чтобы зарегистрировать исправление кода, измените последнюю строку. Исправление создаст документ, полученный после добавления модификатора const к существующему объявлению:

Под символом MakeConstAsync появятся красные волнистые линии. Добавьте объявление в MakeConstAsync , например как указано ниже:

Новый метод MakeConstAsync преобразует Document исходного файла пользователя в новый экземпляр Document, содержащий объявление const .

Создайте новый токен ключевого слова const и вставьте его перед оператором объявления. Не забудьте сначала удалить все элементы trivia из первого оператора объявления и подключить к токену const . Добавьте следующий код в метод MakeConstAsync :

Затем добавьте токен const к объявлению с помощью приведенного ниже кода:

Для выполнения этого кода требуется новое пространство имен. Добавьте следующую директиву using в начало файла.

В конце нужно внести правки. Для этого выполните эти три шага:

  1. Получите дескриптор существующего документа.
  2. Создайте документ, заменив существующее объявление на новое.
  3. Верните новый документ.

Добавьте в конце метода MakeConstAsync приведенный ниже код:

Предупреждение о назначении константы

Мы уже много сделали. Объявления, которые могут быть const , подчеркнуты волнистой линией. Но нам еще нужно с ними поработать. Здесь следует добавить const в объявления i , затем j и k . Но если вы добавите модификатор const в обратном порядке, начиная с k , анализатор выдаст ошибки: k не может быть объявлен как const , пока i и j не являются const . Нужно выполнить дополнительный анализ, чтобы убедиться, что переменные можно объявить и инициализировать различными путями.

Создание модульных тестов

Анализатор и исправление кода работают на простом примере одного объявления, которое может быть константой. Есть множество возможных операторов объявления, где они выдают ошибки. В этих ситуациях можно обратиться к библиотеке модульных тестов, созданной шаблоном. Это гораздо быстрее, чем каждый раз запускать вторую копию Visual Studio.

Откройте файл MakeConstUnitTests.cs в проекте модульного теста. В нем созданы два теста по общим шаблонам для анализатора и для модульного теста исправления кода. Метод TestMethod1 гарантирует, что анализатор не выдаст отчет о диагностике, когда это не нужно. Метод TestMethod2 выдает отчет о диагностике и запускает исправление кода.

Этот шаблон использует пакеты Microsoft.CodeAnalysis.Testing для работы с модульными тестами.

Библиотека тестирования поддерживает специальный синтаксис разметки, в том числе следующие элементы:

  • [|text|] — указывает, что для text предоставляются данные диагностики. По умолчанию эта форма может использоваться только для анализаторов тестирования с одним экземпляром DiagnosticDescriptor , предоставляемым DiagnosticAnalyzer.SupportedDiagnostics .
  • <|ExpectedDiagnosticId:text|>— указывает, что для text предоставляются данные диагностики с Id ExpectedDiagnosticId .

Замените тесты шаблона в классе MakeConstUnitTest следующим методом теста.

Запустите этот тест, чтобы убедиться, что он проходит. Откройте обозреватель тестов в Visual Studio, последовательно выбрав Тест > Windows > Обозреватель тестов. Затем выберите Выполнить все.

Создание тестов для допустимых объявлений

Этот тест также проходит. Далее добавьте методы теста для условий, которые еще не обработаны:

Объявления, которые представляют const , так как они уже являются константами:

Объявления, у которых нет инициализатора, так как нет соответствующего значения:

Объявления, у которых инициализатор не является константой, так как они не могут быть константами времени компиляции:

Переменная i может быть константой, а переменная j — нет. Поэтому этот оператор не может быть объявлением константы.

Снова запустите тесты. Произойдет сбой в новых тестовых случаях.

Обновление анализатора для пропуска верных объявлений

Чтобы отфильтровать код, который соответствует условиям, необходимо преобразовать метод AnalyzeNode анализатора. Эти условия связаны между собой, и изменения в одном из них будут применены ко всем. Внесите следующие изменения в AnalyzeNode :

  • Для объявления одной переменной был выполнен семантический анализ. Этот код должен находиться в цикле foreach , который проверяет все переменные, объявленные в одном и том же операторе.
  • Каждая объявленная переменная должна иметь инициализатор.
  • Каждый инициализатор переменной должен быть константой времени компиляции.

В методе AnalyzeNode замените исходный семантический анализ:

приведенным ниже фрагментом кода:

Первый цикл foreach проверяет каждое объявление переменной с помощью синтаксического анализа. В первой проверке подтверждается наличие инициализатора. Во второй — что этот инициализатор является константой. Во втором цикле запускается исходный семантический анализ. Семантические проверки проходят в отдельных циклах, так как они серьезно влияют на производительность. Снова запустите тест. Все проверки должны быть пройдены.

Финальные штрихи

Вы почти у цели. Анализатор должен обработать еще несколько условий. Пока пользователь пишет код, Visual Studio вызывает анализаторы. Часто бывает так, что анализатор вызван для кода, который не компилируется. Метод AnalyzeNode диагностического анализатора не проверяет, можно ли преобразовать значение константы в тип переменной. Поэтому в текущей реализации все неправильные объявления, такие как int i = "abc" , преобразуются в локальные константы. Добавьте метод теста для этого случая:

Кроме того, ссылочные типы обрабатываются неправильно. Единственное допустимое значение константы для ссылочного типа — null , кроме случаев с использованием System.String, когда допускаются строковые литералы. Другими словами, const string s = "abc" является допустимым, а const object s = "abc" — нет. Этот фрагмент кода проверяет это условие:

Чтобы убедиться в том, что можно создать объявление константы для строки, добавьте еще один тест. В приведенным ниже фрагменте кода определен как код, вызывающий диагностику, так и код после исправления:

К счастью, все вышеперечисленные ошибки можно устранить с помощью методов, которые вы только что изучили.

Затем проверьте каждый инициализатор внутри цикла foreach , чтобы убедиться в том, что его можно преобразовать в тип переменной. Убедившись в том, что инициализатор является константой, добавьте приведенную ниже проверку:

Следующее изменение основано на последнем. Перед закрывающей фигурной скобкой первого цикла foreach добавьте приведенный ниже код. Он проверит тип локального объявления, когда константа является строкой или имеет значение null.

Необходимо заменить ключевое слово var правильным именем типа в вашем поставщике исправлений кода. Вернитесь к MakeConstCodeFixProvider.cs. Код, который вы добавите, выполняет следующие шаги:

  • Проверяет, является ли объявление var , если да:
  • Создает тип для выводимого типа.
  • Проверяет, что объявление типа не является псевдонимом. Если это так, можно объявить const var .
  • Проверяет, что var не является именем типа в программе (если это так, const var является допустимым).
  • Упрощает полное имя типа.

Кажется, что здесь довольно много кода. Но это не так. Замените строку, которая объявляет и инициализирует newLocal приведенным ниже кодом. Он выполняется сразу после инициализации newModifiers :

Чтобы использовать тип Simplifier, потребуется добавить одну директиву using :

Запустите тесты. Они все должны быть пройдены. Можете поздравить себя, запустив готовый анализатор. Чтобы запустить проект анализатора во втором экземпляре Visual Studio с загруженным расширением Roslyn (предварительная версия), нажмите клавиши CTRL + F5 .

В конце добавьте приведенный ниже код:

После этого только две переменные будут подчеркнуты красными волнистыми линиями. Добавьте const в i и j . Появится предупреждение, указывающее на то, что k может быть const .

Читайте также: