. Прежде всего необходимо создать форму — другими словами, экземпляр объекта
SquareRootForm
. Это делает первая строка кода:
SquareRootForm TheMainForm = new SquareRootForm;
Очевидно, что этот код нельзя сравнить с соответствующим кодом VB, потому что такие команды VB недоступны как исходный код, но можно сделать сравнение, если представить, что в некотором коде VB необходимо создать диалоговое окно. В VB это будет выглядеть примерно следующим образом:
Dim SomeDialog As MyDialogClass
Set SomeDialog = New MyDialogClass
В
этом коде VB сначала объявляется переменная, которая является объектной ссылкой —
SomeDialog
будет ссылаться на экземпляр
MyDialogClass
. Затем реально создается экземпляр объекта с помощью ключевого слова
New
из VB и присваивается переменной ссылка на этот объект.
Это совпадает с тем, что происходит в коде C#: объявляется переменная с именем
TheMainForm
, которая является ссылкой на объект
SquareRootForm
, затем используется ключевое слово C#
new
для создания экземпляра
SquareRootForm
, и после этого мы задаем переменной ссылку на этот объект. Основное синтаксическое различие состоит в том, что C# позволяет объединить обе операции в одной инструкции таким же образом, как ранее сразу объявлялась и инициализировалась переменная
NumberInput
. Можно также заметить скобки после выражения new — это требование C#. При создании объектов всегда необходимо записывать эти скобки, потому что C# интерпретирует создание объекта несколько похоже на вызов метода, так что даже можно иногда передавать параметры в вызов new, чтобы указать, как желательно инициализировать новый объект. В данном случае параметры не передаются, но скобки все равно должны использоваться.
Классы С#
До сих пор говорилось, что классы C# похожи на модули классов в VB. Мы уже видели одно различие, заключающееся в том, что классы C# допускают статические методы. Приведенный выше код метода
Main
подчеркивает теперь еще одно различие: если делается что-то подобное в VB, то необходимо также задать для созданного объекта значение
Nothing
, когда работа с ним будет закончена. Однако ничего подобного не появляется в коде C#, так как в C# этого делать вовсе не нужно.
Причина этого различия состоит в том, что классы C# являются более эффективными и динамичными, чем их соответствующие аналоги в VB. Объекты классов VB являются на самом деле объектами COM, то есть каждый из них включает некоторый сложный код, который проверяет, сколько ссылок на объект поддерживается, поэтому каждый объект может разрушить себя, когда обнаружит, что он больше не нужен. В VB, если не задать объектную ссылку
Nothing
после завершения работы с объектом, это будет рассматриваться как плохая практика программирования, так как это означает, что объект не знает, что он больше не нужен, поэтому он может висеть в памяти возможно до окончания всего процесса.
Однако по соображениям производительности объекты C# не выполняют проверку такого рода. Вместо этого C# использует механизм, называемый сборкой мусора. При этом вместо того, чтобы каждый объект проверял, что он должен все еще существовать, среда выполнения .NET время от времени передает управление так называемому сборщику мусора. Сборщик мусора исследует состояние памяти, используя очень эффективный алгоритм для идентификации тех объектов, которые
больше не нужны коду, и удаляя их. При наличии такого механизма неважно сбрасываются ли ссылки, когда работа с ними закончена, обычно достаточно просто подождать, пока переменная выйдет из области видимости.
Но если желательно задать ссылочную переменную, которая ни на что не указывает, то соответствующим ключевым словом C# является
null
, которое означает то же самое, что и
Nothing
в VB. Следовательно, там, где в VB было бы написано:
Set SomeDialog = Nothing;
в C# будет написано:
TheMainForm = null;
Заметим, что это само по себе делает не так уж много в C#, поскольку объект все равно не будет разрушен, пока не вызовется сборщик мусора.
Вход в цикл сообщений
Рассмотрим теперь конечную инструкцию в основном методе:
Application.Run(TheMainForm);
Эта инструкция запускает цикл сообщений. На самом деле здесь вызывается статический метод
Run
класса
System.Windows.Forms.Application
. Этот метод обрабатывает цикл сообщений. Он переводит приложение (или, строго говоря, поток выполнения) в спящее состояние и просит Windows разбудить его, когда произойдет интересное событие. Метод
Run
может получать один параметр, являющийся ссылкой на форму, которая будет обрабатывать все события.
Run
заканчивается, когда произойдет и обработается событие, дающее указание форме завершить работу.
Когда метод
Run
подходит к концу, то и метод
Main
завершается. Так как этот метод был точкой входа в программу, то по его завершении выполнение всего процесса останавливается.
Один элемент синтаксиса в приведенных выше инструкциях, который может показаться удивительным, состоит в том, что при вызове метода
Run
используются скобки, даже хотя никакое возвращаемое значение из этого метода не используется, и, следовательно, выполняется вызов, эквивалентный вызову подпрограммы в VB. VB в этом случае не требует скобок, но в C# существует правило, что при вызове метода всегда используются скобки.
При вызове любого метода в C# всегда используйте скобки, независимо от того, будет или нет использоваться возвращаемое значение.
Класс формы SquareRoot
Мы видели, как C# запускает цикл сообщений, но мы еще не изучили процесс вывода и создания самой формы. Мы также не определились с вопросом о вызове обработчиков событий. Упоминалось, что Windows вызывает такие обработчики событий, как метод
OnClickButtonResults
. Но как Windows узнает, что нужно вызвать этот метод? Мы найдем ответы на все наши вопросы в определении класса
SquareRootForm
и в его базовом классе
Form
.
Отметим сначала, что класс
SquareRootForm
имеет достаточно много полей-членов. (Поле-член является выражением C# для переменной, которая определена как член класса. Можно представлять ее как переменную VB, которая имеет областью действия форму, или как переменную VB, которая определена в качестве члена модуля класса. Каждая такая переменная связана с определенным экземпляром класса — определенным объектом — и остается в области действия до тех пор, пока существует содержащий ее объект):