Технология IntelliSense в Visual Studio
89Программы --- Visual Studio --- Технология IntelliSense
Одним из достижений, которым давно славится компания Microsoft, является автоматическая помощь при редактировании кода. В ранних версиях среды Visual Basic уже была частично реализована технология IntelliSense, но с появлением системы Visual Studio .NET компания Microsoft распространила эту технологию на всю среду интегрированной разработки. В последних выпусках системы технология IntelliSense стала настолько вездесущей, что ее в шутку стали называть IntelliSense Everywhere.
В этой статье описываются многочисленные способы применения технологии IntelliSense, помогающие разработчикам писать программы. К ним относятся обнаружение и исправление синтаксических ошибок, использование контекста и автоматическое дополнение имен переменных.
IntelliSense - это общее название автоматизированной справочной системы и технологии, лежащей в основе приложений, созданных с помощью инструментов компании Microsoft. Наиболее широко известным аспектом технологии IntelliSense является подчеркивание волнистой линией слов с орфографическими ошибками в текстовом редакторе Microsoft Word, а также небольшие визуальные индикаторы в листах электронной таблицы Microsoft Excel, информирующие пользователя о том что содержание конкретной ячейки не соответствует ожидаемому.
Даже эти простые индикаторы позволяют быстро выполнять соответствующие действия. Например, если щелкнуть правой кнопкой на слове, подчеркнутом красной волнистой линией в текстовом редакторе Word, отобразится список предлагаемых альтернатив. Другие приложения имеют аналогичные возможности.
В системе Visual Studio уже довольно давно были реализованы аналогичные возможности. Фактически простейшие функции технологии IntelliSense были реализованы уже в среде разработки Visual Basic 6. С каждым новым выпуском системы Visual Studio компания Microsoft совершенствовала технологию IntelliSense, делая ее все более контекстно-чувствительной и внедряя ее более широко, чтобы разработчик всегда мог легко получить необходимую информацию.
В системе Visual Studio 2013 название IntelliSense относится к большому количеству функций, начиная с визуальной реакции на неправильный код и интеллектуальных дескрипторов для проектирования форм до комбинаций клавиш, нажатие которых приводит к вставке целых фрагментов кода. Эти свойства, вместе взятые, обеспечивают разработчику более глубокое понимание происходящего, более высокую эффективность его работы и позволяют ему контролировать свою программу. Некоторые из этих возможностей для системы Visual Studio 2013 являются новыми. К ним относятся, например, режим подсказок (suggestion mode) и генерация кода в зависимости от его использования (Generate From Usage). Эти возможности предназначены для поддержки альтернативного стиля разработки, получившего название разработка через тестирование (test-driven development - TDD).
Основы технологии IntelliSense
Простейшим свойством технологии IntelliSense является немедленная реакция на неправильный код. На рисунке ниже приведен один из примеров, в котором для инициализации объекта используются данные неизвестного типа. Поскольку тип этих данных неизвестен в том месте, где введен код, система Visual Studio подчеркивает строку красной (для языка C#) или синей (для языка VB) волнистой линией, чтобы обозначить проблему.
Изменить цвет линии подчеркивания можно с помощью группы переключателей Fonts and Colors в окне Options.
Оставив курсор мыши над неправильным фрагментом кода, разработчик увидит подсказку, объясняющую проблему. В данном примере курсор находится над типом данных, поэтому разработчик увидит подсказку «The type or namespace name 'Customer' could not be found».
Система Visual Studio имеет возможность обнаруживать такие ошибки, потому что она непрерывно осуществляет предварительную компиляцию кода, который вводится разработчиком, и ищет все, что может привести к ошибкам компиляции. Если бы разработчик добавил класс Customer в свой проект, то система Visual Studio автоматически обработала бы это действие и удалила бы маркер, поставленный средствами IntelliSense.
На рисунке ниже показан интеллектуальный дескриптор, ассоциированный с этой ошибкой. Он применяется только к ошибкам, для которых система Visual Studio 2013 может предложить конструктивный способ исправления. Непосредственно под неправильным фрагментом кода на экране появляется небольшой синий (для языка C#) или красный (для языка VB) маркер в виде прямоугольника. Поместив курсор мыши на этот маркер, разработчик увидит меню команд интеллектуального дескриптора для ошибок данного типа. В данном случае это меню содержит команды для генерации пользовательского класса Customer, с помощью которого система Visual Studio может определить способ его использования.
Для вызова интеллектуального дескриптора IntelliSense во всех приложениях компании Microsoft используется комбинация клавиш <Shift+Alt+F10>, но в системе Visual Studio 2013 предложена более удобная комбинация <Ctrl+.>.
Технология интеллектуальных дескрипторов, применяемая в системе Visual Studio, предназначена не только для редактирования кода. По существу, система Visual Studio 2013 позволяет применять интеллектуальные дескрипторы и к визуальным элементам управления, когда разработчик редактирует форму или элемент управления в окне Design view.
Когда разработчик выбирает команду, имеющую интеллектуальный дескриптор, в правом верхнем углу элемента управления появляется маленький треугольник. Для того чтобы открыть список Tasks для интеллектуального дескриптора, необходимо щелкнуть на этой кнопке. Комбинации клавиш, вызывающие интеллектуальный дескриптор, применяются и для визуальных элементов управления.
Дополнение слова и фраз
Мощь технологии IntelliSense в системе Visual Studio 2013 становится очевидной сразу, как только пользователь начинает набирать код. По мере набора текста на экране открываются разнообразные списки, помогающие выбрать правильные типы членов класса, функций и их параметров, тем самым уменьшая количество потенциальных ошибок компиляции еще до того, как разработчик закончит набирать текст программы. Ознакомившись с функционированием инструментов IntelliSense, легко заметить, что существует возможность значительно сократить объем кода, который требуется набрать на самом деле. Это особенно важно для пользователей, работающих на таких многословных языках, как Visual Basic.
В системе Visual Studio 2013 технология IntelliSense проявляет себя сразу, как только программист начинает набирать текст в окне редактора кода. На рисунке ниже показано, как работает технология IntelliSense в ходе создания цикла for в программе на языке C#. Как только программист наберет букву f, в левой части изображения откроется список доступных слов, начинающихся с буквы f, который постепенно сокращается по мере набора остальных букв. Легко заметить, что этот список содержит все варианты - инструкции, классы, методы и свойства, - содержащие введенные буквы (в данном случае для всех имен, содержащих слово for).
Несмотря на полезность списка IntelliSense, учитывающего вводимые программистом буквы, этот инструмент является "обоюдоострым". Довольно часто разработчикам приходится искать переменную или член класса, не зная их полное имя. В этом случае можно ввести первые несколько букв наугад, а затем просмотреть список в поисках правильного варианта. Очевидно, что этот прием не сработает, если введенные буквы уже исключили правильный вариант. Для того чтобы увидеть полный список вариантов, нажмите клавишу <Backspace>, пока список IntelliSense открыт.
В старых версиях системы Visual Studio (ниже 2010) технология IntelliSense позволяла находить лишь члены классов, имена которых начинались с символов, набранных программистом в окне редактора кода. Начиная с системы Visual Studio 2010 это не так. Теперь можно найти слова, которые появляются и в середине имен членов класса. Для этого система осуществляет поиск границ слова в именах членов классов. На рисунке ниже приведен пример на языке C#, в котором, набрав слово Console.In, пользователь получает варианты In, InputEncoding, OpenStandardInput, SetIn и TreatControlCAsInput, но не LargestWindowHeight, несмотря на то, что это слово содержит подстроку "in".
Если вы точно знаете, что ищете; введите первую букву каждого слова в верхнем регистре. Например, если набрать System.Console.OSI, то подсистема IntelliSense найдет слово OpenStandardInput.
Если информация, выдаваемая средствами IntelliSense, мешает увидеть другие строки программы или пользователь хочет просто скрыть список, достаточно нажать клавишу <Esc>. В качестве альтернативы, если требуется лишь увидеть строки программы, скрытые за списком IntelliSense, не закрывая его полностью, можно нажать и удерживать клавишу <Ctrl>. В этом случае список IntelliSense станет полупрозрачным и позволит увидеть скрытый под ним код:
Список IntelliSense предназначен не только для удовлетворения информационных потребностей. Разработчик может выбрать элемент этого списка, и система Visual Studio вставит его полный текст в окно редактора кода. Выбрать элемент в списке можно разными способами. Например, можно дважды щелкнуть мышью на требуемом элементе; можно также использовать клавиши с изображениями стрелок для выбора разных элементов, а затем нажать клавишу <Enter> или <Tab>, чтобы вставить в программу текст; и наконец, когда элемент в списке подсвечен, он автоматически будет выбран, если пользователь введет символ фиксации (commit character). Символами фиксации называют символы, которые не допускаются в именах членов классов. Примерами таких символов являются круглые и фигурные скобки, математические символы и двоеточие.
Список членов классов
Поскольку технология IntelliSense разрабатывается уже давно, большинство разработчиков знакомы со списком членов классов, который появляется при наборе имен, завершающихся точкой. Это значит, что программист собирается сослаться на член класса и система Visual Studio автоматически выводит список членов классов, доступных для данного объекта:
При первом открытии списка членов класса, доступных для данного объекта, система Visual Studio выводит список в алфавитном порядке, оставляя видимой его верхнюю часть. Однако, если этот список уже использовался ранее, система подсвечивает последний член, к которому обращался разработчик, чтобы ускорить выполнение повторяющихся действий.
На рисунке выше продемонстрирован также еще один полезный аспект списка членов классов для программистов, работающих на языке Visual Basic. Корешки закладок Common и All (в нижней части списка членов класса) позволяют увидеть либо совместно используемые члены классов, либо их полный список. Фильтровать список свойств, методов и событий по свойствам доступа можно только для языка Visual Basic.
Режим подсказок
По умолчанию, когда система Visual Studio 2013 выводит на экран список членов IntelliSense, можно выбрать только один элемент списка. По мере ввода последующих символов подсветка перемещается на элемент, который лучше остальных соответствует набранным символам. Если нажать клавиши <Enter> или <Space> или набрать один из символов фиксации (например, открывающую скобку), то выделенный в данный момент элемент списка будет вставлен в окно редактора кода. Это поведение, предусмотренное по умолчанию, называется режимом дополнения (completion mode).
Как правило, режим дополнения обеспечивает ожидаемое функционирование системы и позволяет сэкономить много усилий, связанных с набором текста, но в некоторых случаях могут возникнуть проблемы. Один из них возникает при разработке через тестирование, когда пользователь часто ссылается на члены классов, которые еще не были определены. Это вынуждает систему IntelliSense выбирать члены классов, не устраивающие программиста, и вставлять нежелательный текст.
Для того чтобы этого избежать, компания Microsoft в интегрированной среде разработки Visual Studio 2010 предложила новый режим функционирования системы IntelliSense, который называется режимом подсказок (suggestion mode). Когда система IntelliSense работает в режиме подсказок, один из членов классов в списке находится в фокусе, но не выбирается по умолчанию. По мере набора текста система IntelliSense перемещает фокус на элемент, наиболее точно соответствующий набранным символам, но не вставляет его автоматически. Вместо этого набранные символы вставляются в начало списка IntelliSense, и если пользователь введет один из символов фиксации или нажмет клавишу <Space> или <Enter>, то в окно редактора будет вставлена точно набранная строка.
Элементы списка IntelliSense можно по-прежнему выбирать с помощью навигационных клавиш или клавиши <Tab>.
На рисунке ниже приведен пример задачи, для решения которой предназначен режим подсказок. В левой части рисунка программист набирает текст для нового метода Load из класса CustomerData. Класс CustomerData еще не содержит метода Load, но в нем уже есть класс LoadAll. Справа, показано, что программист набрал имя Load, за которым следует открывающая круглая скобка. Система IntelliSense неправильно предположила, что разработчик подразумевал метод LoadAll, и вставила его в окно редактора.
Для того чтобы избежать этого, можно включить режим подсказок, нажав клавиши <Ctrl+Alt+Space>. Теперь, когда программист наберет имя Load, оно появится в начале списка IntelliSense. Набрав открывающую круглую скобку, разработчик получит метод Load, что и требовалось:
Система IntelliSense останется в режиме подсказок, пока пользователь не нажмет комбинацию клавиш <Ctrl+Alt+Space>, тем самым включив режим дополнения.
Stub Completion
Кроме автоматического дополнения слов и фраз, система IntelliSense может также работать в режиме заглушки. Это свойство можно увидеть в среде разработки Visual Basic, когда программист создает функцию, вставляя ее объявление и нажимая клавишу <Enter>. Среда Visual Studio автоматически переформатирует строку, добавляя соответствующее ключевое слово ByVal для параметров, которые не были явно определены своим контекстом, и строку End Function, завершающую код функции. Другой пример можно увидеть при редактировании XML-документа. Когда программист набирает открывающий дескриптор (open tag) нового элемента, система Visual Studio автоматически добавляет закрывающий дескриптор для него.
Режим заглушки в системе Visual Studio 2013 представляет собой новый этап, позволяя программистам делать то же самое при перегрузке интерфейсов и методов. Когда разработчик добавляет определенные конструкции кода, такие как интерфейс или определение класса, в языке C#, система Visual Studio дает ему возможность автоматически генерировать код, необходимый для реализации данного интерфейса. Для того чтобы продемонстрировать, как это работает, рассмотрим этапы, которые проходит система IntelliSense, генерируя реализацию интерфейса для простого класса.
Запускаем систему Visual Studio 2013 и создаем проект типа C# Windows Forms Application. Когда интегрированная среда разработки сгенерирует первоначальный код, открываем файл Form1.cs в окне редактора кода.
В начало файла добавляем директиву using, чтобы открыть доступ к пространству имен System.Collections.Generic.
using System.Collections.Generic;
Добавляем в начало определения класса строку:
public class CustomerCollection : IEnumerable<Customer>
Поскольку мы набираем интерфейс IEnumerable, система Visual Studio сначала добавляет красную волнистую линию в конце фрагмента, чтобы показать, что в определении класса нет фигурных скобок, а затем добавляет индикатор интеллектуального дескриптора перед именем интерфейса:
Устанавливаем курсор мыши на индикатор интеллектуального дескриптора. Когда появится пиктограмма, щелкаем на ней, чтобы открыть меню доступных команд, как показано на рисунке ниже:
Выбираем команду Implement interface IEnumerable<Customer>, и система Visual Studio 2013 автоматически генерирует оставшуюся часть кода, необходимую для завершения минимального определения интерфейса. Поскольку система видит что определение класса является неполным, она одновременно добавляет фигурные скобки, чтобы исправить эту ошибку.
Интерфейс, который получится в результате, показан на рисунке ниже:
Обработчики событий также можно автоматически сгенерировать с помощью системы Visual Studio, (например, myBase.OnClick+=), система Visual Studio выполняет автоматическое дополнение, которое можно подтвердить, нажав клавишу <Tab>.
Свойство Generate From Usage
Вместо генерирования кода в соответствии с существующим определением иногда удобнее генерировать определение кода элемента в зависимости от способа, которым он используется. Это особенно удобно при разработке через тестирование, когда разработчик пишет тесты для классов, которые еще не определены. В этом случае желательно иметь возможность генерировать классы по самим тестам. Для этой цели в языки C# и Visual Basic было включено новое свойство - Generate From Usage.
Для того чтобы понять, как это свойство можно использовать на практике, рассмотрим этапы создания очень простого класса Customer с помощью некоего клиентского кода, использующего этот класс, а затем генерирующего его в зависимости от способа использования:
Запускаем систему Visual Studio 2013 и создаем проект типа C# Command Line. Когда интегрированная система разработки будет готова к работе, открываем файл Program.cs.
Включаем в метод Main следующий код C#:
Customer c = new Customer { FirstName = "Joe", LastName = "Smith" }; Console.WriteLine(c.FullName); c.Save();
Оба раза, когда имя Customer встречается в тексте программы, оно подчеркивается красной волнистой линией. Щелкаем правой кнопкой на одном из них и выбираем команду Generate Class. Она создает новый класс Customer в нашем проекте. Открываем файл Customer.cs и видим пустое объявление класса. Система Visual Studio выяснит, что FirstName, LastName, FullName и Save не являются членами класса.
Для каждого не существующего в классе свойства щелкаем правой кнопкой на его имени и выбираем команду Generated Property. Снова открываем файл Customer.cs и видим, что система Visual Studio способна сама создать его реализацию.
То же самое можно повторить для метода Save, щелкнув на его имени правой кнопкой и выбрав команду Generated Method Stub.
Несмотря на то что сгенерированные свойства и классы можно использовать сразу, заглушки методов создаются так, чтобы они генерировали исключение NotImplementedException.
Если неопределенный код, который разработчик пытается сгенерировать, является типом, то можно выбрать команду Generate Class или Generate New Type. Если выбрать команду Generate New Type, то откроется диалоговое окно Generate New Туре:
Оно предоставляет пользователю много возможностей для конфигурации нового типа, включая выбор его разновидности: класс, перечисление, интерфейс или структура; уровень доступа: открытый (public), закрытый (private) или внутренний (internal), а также его местонахождение.
Информация о параметрах
В старых версиях инструментов разработки программ, выпущенных компанией Microsoft, например в системе Visual Basic 6, как только пользователь создавал вызов Функции, при наборе параметров система IntelliSense сразу выводила на экран информацию о них. К счастью, это невероятно полезное свойство по-прежнему доступно в системе Visual Studio 2013.
Старый способ представления информации о параметрах имел один недостаток: информация появлялась только тогда, когда разработчик действительно модифицировал вызов функции. Следовательно, он мог увидеть полезную подсказку только при создании вызова функции или при его изменении, но не при обычном просмотре кода.
В результате разработчики иногда непреднамеренно вносили ошибки в код программы, поскольку они умышленно модифицировали вызовы функций так, чтобы увидеть информацию о ее параметрах, а потом забывали их исправить.
Система Visual Studio 2013 исключила такой риск ошибок, предоставив команду, которая выводит информацию на экран, не требуя модификации кода. Нажав комбинацию клавиш <Ctrl+K, Ctrl+P>, можно вывести на экран информацию о вызове функции, как показано на рисунке ниже. Кроме того, можно получить доступ к этой информации, выбрав команду Edit --> IntelliSense --> Parameter Info.
На рисунке ниже метод Regex.Replace имеет три параметра, в версии по умолчанию. Если параметр является необязательным, то он выводится в квадратных скобках с указанием его значения по умолчанию. Программисты, работающие на языке VB, уже знакомы с этой синтаксической конструкцией, для языка C# 4.0 она является новой.
Команда Quick Info
Иногда программист хочет видеть информацию об объекте или интерфейсе, не модифицируя его код. Нажав комбинацию клавиш <Ctrl+K>, <Ctrl+I>, можно увидеть короткую подсказку, объясняющую предназначение объекта и способ его объявления:
Комбинации клавиш в системе VS2013 зависят от выбранных параметров инсталляции (например, Visual Basic Developer, Visual C# Developer и т.д.). Все комбинации клавиш в этой статье соответствуют настройкам профиля General Developer Profile.
Эту подсказку можно увидеть также, выбрав команду Edit --> IntelliSense --> Quick.