Симон Робинсон - C# для профессионалов. Том II
2. Классы и наследование C# значительно более объектно-ориентированны, чем в VB, при условии, что весь код является частью класса. Он обеспечивает также исчерпывающую поддержку наследования реализации. На самом деле большинство хорошо спроектированных программ C# будут в значительной степени отвечать этой форме наследования, которая полностью отсутствует в VB.
Основная часть этого приложения посвящена разработке двух примеров, для которых будут закодированы версии на VB и C#. Первый пример является простой формой, запрашивающей у пользователя число и выводящей квадратный корень и знак числа. Сравнивая подробно версии примера на VB и C#, мы увидим базовый синтаксис C# и поймем концепции, которые лежат в основе потока выполнения программы.
Затем будет представлен модуль класса VB, который хранит информацию о сотрудниках, и его эквивалент в C#. Здесь мы начнем знакомиться с реальной мощью C#, так как при добавлении свойств в примеры быстро станет понятно, что VB просто не поддерживает концепции, которые нужны для разработки модуля класса согласно заданным требованиям, и придется продолжать только на C#.
Приложение будет закончено кратким обзором некоторых из оставшихся различий между VB и C#, не показанных в примерах.
Однако прежде чем начать, необходимо разобрать несколько концепций, касающихся классов, компиляции и базовых классов .NET.
Классы
В этом приложении будут достаточно интенсивно использоваться классы C#. Они представляют собой точно определенные объекты, которые подробно рассматриваются в главах 4 и 5. Но для логичности изложения лучше представлять их как эквиваленты C# модулей классов VB, так как они являются достаточно похожими сущностями. Подобно модулю класса VB, класс C# реализует свойства и методы и содержит переменные члены. Так же как для модуля класса VB, можно создавать объекты заданного класса C# (экземпляры класса) с помощью оператора new. За этим сходством, однако, скрывается много различии. Например, модуль класса VB является на самом деле классом COM. Классы C#, напротив, обычно не являются классами COM, но они всегда интегрированы в среду .NET. Классы C# являются также более динамичными чем их аналоги VB/COM, в том смысле, что они обеспечивают более высокую производительность и дают меньшую потерю быстродействия при создании экземпляра. Но эти различия мы почти не будем учитывать при обсуждении языка C#.
Компиляция
Вы наверняка хорошо знаете, что компьютер никогда не выполняет напрямую код на любом языке высокого уровня, будь это VB, C++, С или любой другой язык. Вместо этого весь исходный код сначала транслируется в собственный исполнимый код машины с помощью процесса, обычно называемого компиляцией. При отладке VB предлагает возможность просто выполнить код сразу (то есть, когда каждая строка кода VB компилируется, или в этом случае говорят, что код интерпретируется, так как компьютер готов выполнить эту строку кода) либо произвести полную компиляцию (так, что вся программа сначала транслируется в исполнимый код, а затем начинается его реализация). Выполнение в начале полной компиляции означает, что все синтаксические ошибки обнаруживаются компилятором до того, как программа заработает. Это ведет к более высокой производительности и допускается только в C#.
В C# компиляция делается в два этапа, где первый этап выполняется на так называемом промежуточном языке (IL) Этот этап будем называть собственно компиляцией. Второй этап — преобразование в исполнимый код, происходящее во время выполнения, является более простым этапом, поэтому он не ведет к значительным потерям производительности. Он также не является интерпретацией. Сразу целые части кода преобразуются из IL в язык ассемблера, и полученный исполнимый код на собственном языке машины затем сохраняется, поэтому не требуется его перекомпиляции в следующий раз, когда будет выполняться эта часть кода. Компания Microsoft считает, что в комбинации с различными оптимизациями это, в конечном счете ведет к коду, который действительно выполнится быстрее, чем при использовании предыдущей системы прямой компиляции из исходного кода в собственный исполнимый код. Хотя о существовании IL необходимо помнить, он не будет влиять на обсуждение в этом приложении, так как он реально не влияет на синтаксис языка C#.
Базовые классы .NET
VB не состоит просто из одного языка. Существует большое число связанных с ним функций, скажем, функции преобразования CInt, CStr и т.д., функции файловой системы, функции даты-времени и многие другие. VB также полагается на присутствие элементов управления ActiveX, предоставляющих стандартные элементы управления, которые помещаются на форме,— поля списков, кнопки, текстовые поля и т.д.
C# также полагается на интенсивную поддержку из областей такого вида, но в случае C# поддержка предоставляется с помощью большого множества классов, известного как базовые классы .NET. Эти классы оказывают поддержку почти всем аспектам разработок под Windows. Существуют классы, представляющие все обычные элементы управления, дату, время, доступ к файловой системе, доступ в Интернет, а также многие другие. Здесь подробно не рассматривается библиотека базовых классов .NET, но она часто используется. На самом деле C# очень хорошо интегрирован в пазовые классы .NET, и можно обнаружить, что многие ключевые понятая C# — это просто оболочки определенных базовых классов. В частности, все базовые типы данных C#, которые используются для представления целых чисел, чисел с плавающей точкой, строк и т. д. являются на самом деле базовыми классами.
Одним из важных различий между VB6 и C# в этом отношении является то, что система функций VB является специфической для VB, в то время как базовые класс .NЕТ доступны для любого поддерживающего .NET языка программирования.
Соглашения
В этом приложении код на C# часто сравнивается с Visual Basic. Чтобы облегчить идентификацию кода на двух языках программирования, код C# представлен в том же формате, что и в приложениях В и C:
// Код который уже был показан
// Код C#, на который необходимо обратить внимание или который
// является новым
Однако весь код VB дается в следующем формате:
' Код VB представлен на белом фоне
Пример: Форма для извлечения квадратного корня
В этом разделе мы рассмотрим простое приложение, называемое SquareRoot, которое будет разработано на Visual Basic и на C#. Приложение является обычным диалоговым окном, которое приглашает пользователя ввести число и затем, когда пользователь нажимает кнопку, выводит знак и квадратный корень этого числа. Если число отрицательное, то квадратный корень необходимо вывести как комплексное число, что просто означает извлечение квадратного корня из обратного числа и добавление после него 'i'. Версия C# примера выглядит следующим образом. Версия VB по виду почти идентична, за исключением того, что имеет стандартною пиктограмму VB вместо пиктограммы оконных форм .NET в верхнем левом углу:
Версия SquareRoot на VB
Чтобы это приложение работало в Visual Basic, надо добавить обработчик событий для события нажатия кнопки. Для кнопки задается имя cmdShowResults, а текстовые поля имеют имена txtNumber, txtSign и txtResult. С этими именами обработчик событий выглядит следующим образом:
Option Explicit
Private Sub cmdShowResults_Click()
Dim NumberInput As Single
NumberInput = CSng(Me.txtNumber.Text)
If (NumberInput < 0) Then
Me.txtSign.Text = "Negative"
Me.txtResult.Text = CStr(Sqr(-NumberInput)) & " i"
ElseIf (NumberInput = 0) Then
txtSign.Text = "Zero"
txtResult.Text = "0"
Else
Me.txtSign.Text = "Positive"
Me.txtResult.Text = CStr(Sqr(NumberInput))
End If
End Sub
Это единственный фрагмент кода VB, который необходимо написать.
Версия SquareRoot на C#
На C# также необходимо написать обработчик событий для события нажатия кнопки. Здесь сохраняются те же имена кнопки и текстовых полей, но на C# код выглядит следующим образом:
// Обработчик событий нажатия пользователем кнопки Show Results.
// выводится квадратный корень и знак числа
private void OnClickShowResults(object sender, System.EventArgs e) {
float NumberInput = float.Parse(this.txtNumber.Text);
if (NumberInput < 0) {
this.txtSign.Text = "Negative";
this.txtResult.Text = Math.Sqrt(-NumberInput).ToString() + " i";
} else if (NumberInput == 0) {
txtSign.Text = "Zero";
txtResult.Text = "0";
} else {
this.txtSign.Text = "Positive";
this.txtResult.Text = Math.Sqrt(NumberInput).ToString();
}