Пользуемся подсказкой, чтобы узнать объектные типы

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

Рассмотрим на простейшем примере, как для этого пользоваться подсказкой. Пусть мы, например, хотим покрасить метку в красный цвет, но забыли, как это делается. В результате мы не знаем, как правильно написать – так:

Label1.BackColor = Color.Red

так:

Label1.BackColor = Brushes.Red

или так:

Label1.BackColor = Pens.Red

VB путем подчеркивания вежливо подсказывает нам, что два последних варианта неверны. Но мы не понимаем, почему. И хотим знать, чтобы не ошибаться в дальнейшем. Такое желание достойно уважения и его необходимо удовлетворить.

Источник многих ошибок – несоответствие типов. Поэтому нам для начала нужно точно знать тип каждого элемента в написанных строках. Потренируемся. Начнем с правильной строки.

Label1.BackColor = Color.Red. Поставим мышь на слово Label1. Всплывает подсказка:

Friend Dim WithEvents Label1 As System.Windows.Forms.Label

Что это такое? Не обращаем внимания на слова Friend и WithEvents. Остается

Dim Label1 As System.Windows.Forms.Label

Это не что иное, как объявление метки. Мы его не делали, VB сделал его сам в скрытой части окна кода (см. 6.1.3). Мы видим, что метка Label1 имеет тип System.Windows.Forms.Label, то есть принадлежит классу Label, входящему в пространство имен System.Windows.Forms.

Поставим мышь на слово BackColor. Всплывает подсказка:

Public Overridable Overloads Property BackColor() As System.Drawing.Color

Не обращаем внимания на слова Public Overridable Overloads. Остается

Property BackColor() As System.Drawing.Color

Слово Property означает «свойство». Это не что иное, как подсказка о типе свойства BackColor. Мы видим, что свойство метки BackColor имеет тип System.Drawing.Color, то есть является структурой Color, входящей в пространство имен System.Drawing.

Не задавайте мне сейчас вопросов, вроде «Как может цвет быть какой-то там структурой?» или других вопросов о «смысле». Вам даже не нужно понимать, похожа ли структура на объект. Понимание таких вещей придет к нам позднее. Сейчас нам важно уяснить следующее: Некоторый элемент (в нашем случае – свойство BackColor) может принадлежать одному классу или объекту (Label1), а его значение может иметь тип совсем другого класса, объекта или чего-нибудь еще (структура Color). Всегда помните эту разницу. Это нормально. Это в порядке вещей.

Поставим мышь на слово Color. Всплывает подсказка:

Structure Color

Здесь все понятно.

Далее. У структуры Color есть свойства и одно из них стоит после точки. Поставим мышь на слово Red. Всплывает подсказка:

Public Shared Overloads ReadOnly Property Red() As System.Drawing.Color

Не обращаем внимания на слова Public Shared Overloads ReadOnly. Получается

Property Red() As System.Drawing.Color

Мы видим, что Red – это свойство структуры Color и оно же имеет тип Color, то есть тип той же самой структуры. А почему бы и нет, Семен Семеныч Семенов? Опять же, пока важно не это.

Оператор присваивания Label1.BackColor = Color.Red присваивает свойству BackColor объекта Label1 свойство Red структуры Color. Мы только что убедились, что типы обоих свойств совпадают, а это значит, что совместимость типов соблюдена и присвоение прошло без осложнений.

Label1.BackColor = Brushes.Red. Теперь посмотрим, к чему придирается VB в операторе Label1.BackColor = Brushes.Red. Что касается левой части оператора, то там все то же, что и в правильной строке. Посмотрим на подчеркнутую правую часть.

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

Чтобы вспомнить, мы можем воспользоваться средствами помощи или Object Browser, как мы это делали в 6.2.8. Я поступлю проще – напишу какой-нибудь правильный оператор, в котором выражение Brushes.Red не будет подчеркнуто, и поставлю мышь на слово Brushes. Всплывает подсказка:

Class Brushes

Все ясно. Это класс с именем Brushes.

Поставим мышь на слово Red. Всплывает подсказка:

Public Shared Overloads ReadOnly Property Red() As System.Drawing.Brush

Она единственным (самым правым) словом отличается от аналогичной подсказки для свойства Red структуры Color. Но это слово решает все.

Мы видим, что в данном случае Red – это свойство класса Brushes, и оно имеет тип Brush. Класс Brushes и класс Brush – это разные классы и вы не должны их путать, несмотря на то, что их похожее написание провоцирует спекуляции на тему некоей смысловой связи этих классов. Чтобы правильно пользоваться обоими классами, нет никакой необходимости вникать в наличие или отсутствие этой связи.

Мы видим, что свойство Red принадлежит классу Brushes, а само имеет значение совсем другого типа – класса Brush. Тоже в порядке вещей. Привыкайте.

Главный вывод таков. Неправильный оператор присваивания пытается присвоить свойству BackColor, имеющему тип Color, свойство Red, имеющее тип Brush. Типы не совпадают и VB бессилен их совместить.

Поставим мышь на подчеркнутую правую часть. Всплывает подсказка

Value of type 'System.Drawing.Brush' cannot be converted to 'System.Drawing.Color'

Переводится подсказка так:

«Значение типа Brush не может быть преобразовано в тип Color».

Как видите, для понимания причин несовместимости нам совсем не понадобилось изучать класс Brush и даже знакомиться с ним.

Label1.BackColor = Pens.Red. Аналогично можете убедиться в неправильности третьей строки, где свойство Red знакомого нам класса Pens имеет неведомый нам тип Pen, то есть его значение принадлежит классу Pen.

Получается не очень логичная с точки зрения здравого смысла вещь: Красный – он и в Африке красный. Зачем же тогда свойство Red разных классов имеет разный тип? Поймете, когда будете писать свои классы.

Параметры методов

В предыдущем подразделе мы разбирались в причинах несовместимости объектных типов в операторе присваивания. Сейчас мы рассмотрим несовместимость объектных типов в параметрах.

Вспомним еще раз Методы, «придирчивые» к типу параметров (6.2.8). Проделаем еще раз то, что мы делали там. Пусть мы, например, забыли параметры метода DrawLine. В результате мы не знаем, как правильно написать – так:

Граф.DrawLine(Pens.Red, 0, 0, 100, 100)

так:

Граф.DrawLine(Brushes.Red, 0, 0, 100, 100)

или так:

Граф.DrawLine(Color.Red, 0, 0, 100, 100)

VB путем подчеркивания подсказывает нам, что два последних варианта неверны. Но нам надо знать, почему. Мы грешим на несовместимость типов и решаем проверить, каким типам принадлежат первый параметр в обращении к методу и первый параметр в объявлении метода.

Граф.DrawLine(Pens.Red, 0, 0, 100, 100). Рассмотрим сначала правильную строку. Поставим мышь на слово Red. Подсказка говорит нам, что свойство Red знакомого нам класса Pens имеет неведомый нам тип Pen, то есть его значение принадлежит классу Pen. Хорошо. Неважно, что класс неведомый, важно, чтобы тип первого параметра тоже был Pen и в объявлении метода.

Как добраться до объявления? Предлагаю 3 способа. Первые два заключаются в использовании системы помощи VB и Object Browser. Я разобрал эти способы в 6.2.8 и тех, кто их совсем забыл, отсылаю туда. Остальным напомню.

1 способ. Поставьте текстовый курсор на название метода DrawLine в окне кода и нажмите клавишу F1. Перед вами возникнет окно помощи, в котором вы увидите заголовки нескольких вариантов метода – процедуры Sub DrawLine. Во всех вариантах вы увидите, что тип интересующего нас первого параметра – Pen. Не путайте с Pens. Все в порядке.

2 способ. Найдите в Object Browser класс Graphics и выделите. В правой панели вы увидите его свойства и методы. Среди них вы найдете и 4 варианта метода DrawLine с указанием параметров.

3 способ я рассмотрю в следующем подразделе.

Граф.DrawLine(Brushes.Red, 0, 0, 100, 100). Теперь рассмотрим вторую строку, ошибочную. Поставим на нее мышь. Перед нами возникает длинная подсказка об ошибке:

Overload resolution failed because no accessible 'DrawLine' can be called with these arguments:

'Public Overloads Sub DrawLine(pen As System.Drawing.Pen, x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer)': Value of type 'System.Drawing.Brush' cannot be converted to 'System.Drawing.Pen'.

'Public Overloads Sub DrawLine(pen As System.Drawing.Pen, x1 As Single, y1 As Single, x2 As Single, y2 As Single)': Value of type 'System.Drawing.Brush' cannot be converted to 'System.Drawing.Pen'.

Переводится она так:

«Ошибка произошла потому, что ни один из вариантов процедуры DrawLine не может быть вызван с такими аргументами (параметрами):

В варианте процедуры 'Public Overloads Sub DrawLine(pen As System.Drawing.Pen, x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer)' значение типа 'System.Drawing.Brush' не может быть преобразовано в 'System.Drawing.Pen'.

В варианте процедуры 'Public Overloads Sub DrawLine(pen As System.Drawing.Pen, x1 As Single, y1 As Single, x2 As Single, y2 As Single)' значение типа 'System.Drawing.Brush' не может быть преобразовано в 'System.Drawing.Pen'.»

Мне кажется, здесь все ясно. Мы ошибочно попытались написать в обращении первым параметром Brushes.Red. Но VB выдал ошибку, поскольку тип свойства Red класса Brushes есть Brush, а для первого параметра требуется Pen.

Аналогичное сообщение вы получите для третьей строки.

IntelliSense

У VB есть средство IntelliSense, помогающее вводить программный текст в окно кода. Его основная цель – сократить время написания операторов, по ходу ввода предлагая программисту подсказки, правильные варианты написания текста и дописывая за него слова.

Перечислю основные возможности IntelliSense:

Список компонентов. Мы с вами уже давно и широко пользуемся этой возможностью. Как только мы ставим точку после имени объекта, перед нами возникает прокручивающийся список всех подходящих компонентов этого объекта, из которого мы мышкой или с клавиатуры выбираем нужный. Когда нужный компонент выбран, рядом с ним возникает подсказка, поясняющая его смысл и значение. Мы нажимаем клавишу Tab или Enter – и компонент появляется в тексте, что избавляет нас от необходимости вводить его вручную.

Подсказка по параметрам – пример 1. Она, непрошенная, сопровождает вас во время ввода параметров процедур и функций. Безусловно, вам она уже, наверное, надоела, а некоторые, возможно, в ней уже разобрались и извлекают из нее пользу. Это, кстати, и есть третий способ добраться до объявления процедуры или функции, упомянутый в предыдущем подразделе. Пришла пора разобрать эту подсказку. Разберем ее сначала на примере вызова функции вычисления абсолютной величины.

Введите текст, приведенный на Рис. 11.2.

Пользуемся подсказкой, чтобы узнать объектные типы - student2.ru

Рис. 11.2

Как только вы введете открывающую скобку, перед вами возникнет подсказка, приведенная на рисунке. Смысл ее не очень понятен, но в ее левом углу мы видим, что имеется семь вариантов написания этой функции, а мы сейчас смотрим на подсказку к 1-му варианту. Щелкая мышкой по стрелкам или с клавиатуры прокрутим список подсказок, пока не доберемся до чего-нибудь более подходящего (я имею в виду 3-й вариант – Рис. 11.3).

Пользуемся подсказкой, чтобы узнать объектные типы - student2.ru

Рис. 11.3

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

Abs (value As Integer) As Integer

Это как раз то, что нужно, чтобы знать правильные типы функции и ее параметров. Функция имеет имя Abs. Слово value – это имя первого параметра. Почему выбрано именно такое имя, не имеет значения. Если вы помните, вы можете для параметров выбирать любые имена. Вы видите, что в этом варианте параметр должен иметь тип Integer. Функция в этом случае, как видите, будет обязана иметь тот же самый тип Integer.

В нижней части подсказки мы видим пояснение для параметра value: Говорится, что это число в диапазоне таком-то (далее идет пояснение диапазона для профессионалов, нам это не нужно, так как мы и без того знаем точное значение этого диапазона).

Введите в качестве параметра какое-нибудь число, переменную или выражение и закройте скобку. Подсказка исчезнет.

Подсказка по параметрам – пример 2. Мы хотим нарисовать залитый эллипс при помощи функции FillEllipse. Введите текст, приведенный на Рис. 11.4 и выберите 2-й вариант подсказки.

Пользуемся подсказкой, чтобы узнать объектные типы - student2.ru

Рис. 11.4

Внутри скобок мы видим 4 запятые. Значит, параметров – 5. Первый из них такой:

brush As System.Drawing.Brush

Слово brush – это имя первого параметра. Начинающего на первых порах может дезориентировать тот факт, что выбрано именно такое имя. Ведь оно совпадает с именем класса Brush. Сказано же: разные вещи называй по-разному! Но опытные программисты знают, что значение и роль какого-нибудь элемента в программной строке зависит не только от его имени, но и от положения в этой строке. Поэтому и не возражают против таких «тезок». Ну, а новичкам приходится привыкать.

Вы видите, что первый параметр должен иметь тип System.Drawing.Brush. Это значит, что он должен быть объектом класса Brush, принадлежащего пространству имен System.Drawing.

Внизу подсказки мы видим пояснение параметра brush: Говорится, что этот объект определяет характеристики заливки.

В дальнейшем мы сами будем создавать кисти. А сейчас воспользуемся готовым объектом – Brushes.Blue (см. Рис. 11.5). Он имеет подходящий тип.

Пользуемся подсказкой, чтобы узнать объектные типы - student2.ru

Рис. 11.5

Как только мы ввели запятую после Brushes.Blue, подсказка изменилась. Теперь полужирным выделен не первый параметр, который мы только что ввели, а второй, который нужно вводить. Вообще правило такое: полужирным выделяется тот параметр, на котором стоит текстовый курсор. И подсказка внизу – для него же. Это удобно.

Имя второго параметра – x. Его тип в этом варианте – Single. Читаем внизу пояснение: x – координата верхнего левого угла воображаемого прямоугольника, описанного вокруг эллипса.

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

Подсказка в подсказке. Попробуем в качестве какого-нибудь параметра этой функции ввести выражение, содержащее другую функцию – Math.Abs(-20) + 10. Как только мы откроем скобку после Abs, VB услужливо сменит подсказку для процедуры FillEllipse на подсказку для функции Abs (см. Рис. 11.6).

Пользуемся подсказкой, чтобы узнать объектные типы - student2.ru

Рис. 11.6

Когда вы закроете скобку после функции Abs, вернется старая подсказка. Правда, у меня не сохранялся номер варианта старой подсказки.

Всплывающая подсказка. Ей мы широко пользовались. Если поставить мышь на любое имя в окне кода, всплывет подсказка о типе элемента с этим именем.

Дописываю слово. Начните писать какое-нибудь имя, например, имя пространства имен Microsoft. Написав Mic, вы устали и хотите, чтобы VB вместо вас дописал это слово. Нажмите комбинацию клавиш Alt-стрелка направо или Ctrl-пробел – и VB допишет или предложит варианты.

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

Глава 12. Графика– 2

Ну вот. Вы сейчас уже достаточно подготовлены, чтобы воспринять идеи следующих трех глав. Вас ждут конкретные и привлекательные вещи: графика, работа со временем, таймером, мышью и клавиатурой. И два интересных проекта: Будильник и Гонки.

Наши рекомендации