Информационные системы
CLR - часть 2
 


Информационные технологии

Технология .Net

Что такое .Net
.Net Framework
VB.Net: дорога в будущее
Типы данных VB.Net
Впечатление от VB.Net
Ссылки по Net

1. CLR - Введение
2. CLR - Часть 2
3. Visual Studio.Net
4. Библиотека классов
5. Массивы и коллекции
6. Строки
7. Файлы и каталоги
8. Потоки ввода-вывода

КомпьютерПресс



Инф. системы
Модель города
Книги и статьи

ЭРА

1С:Предприятие

Интересное

Форум

mista.ru / Инф. технологии / Технология .Net / CLR - часть 2

Алексей Федоров
КомпьютерПресс
1'2002

Common Type System
Данные со значениями
   Перечисления
   Структуры
Ссылочные типы
   Классы
   Методы
   События
   Делегаты
   Массивы
   Интерфейсы
   Указатели
Заключение

В предыдущем номере мы начали знакомство с Microsoft .NET Framework — ключевым компонентом Microsoft .NET, представляющим собой платформу для создания, внедрения и выполнения Web-сервисов и приложений. Мы рассмотрели основные компоненты Microsoft .NET Framework и кратко описали их назначение. Мы также начали более подробное рассмотрение Common Language Runtime (CLR) — среды выполнения .NET-приложений. В этой части статьи мы продолжим разговор о Common Language Runtime и остановимся на Common Type System.


Common Type System

Common Type System (CTS) — это последний компонент Common Language Runtime, который мы рассмотрим в данной статье. CTS определяет типы, поддерживаемые Common Language Runtime. Типы можно условно разделить на две большие группы: данные со значениями (value types) и ссылочные типы (reference types). В каждой группе существуют подтипы (см. рис. 1)

.

Данные со значениями описывают значения, представляемые последовательностью байтов. Для таких типов существует понятие идентичности. Например, 32-битное целочисленное значение занимает определенную последовательность байтов. Два 32-битных целочисленных значения идентичны, если они содержат одно и то же число. К данным со значениями также относятся встроенные типы, рассматриваемые ниже. Ссылочные типы служат для описания значений, представляемых местонахождением последовательности байтов. Ссылочные типы подразделяются на три категории:

  • Объектные типы — содержат самоописываемые значения. Некоторые объектные типы (абстрактные классы) содержат только частичное описание значений.
  • Интерфейсные типы — всегда содержат только частичное описание значений.
  • Указательные типы — во время компиляции содержат описание значения, представленного адресом в памяти.

Составной частью Common Type System являются встроенные типы (табл. 1), непосредственно поддерживаемые виртуальной исполняющей системой (Virtual Execution System, VES).

Тип Имя в библиотеке классов Описание
bool System.Boolean Хранит значение true/false
char System.Char Хранит 16-битный Unicode-символ
object System.Object Хранит объектное значение
string System.String Хранит Unicode-строку
float32 System.Single Хранит 32-битное значение с плавающей точкой
float64 System.Double Хранит 64-битное значение с плавающей точкой
int8 System.SByte Хранит знаковое 8-битное целочисленное значение
int16 System.Int16 Хранит знаковое 16-битное целочисленное значение
int32 System.Int32 Хранит знаковое 32-битное целочисленное значение
int64 System.Int64 Хранит знаковое 64-битное целочисленное значение
natural int System.IntPtr Хранит знаковое целочисленное значение естественного размера
natural unsigned int System.UIntPtr Хранит беззнаковое целочисленное значение естественного размера
typedref System.TypedReference Указатель на тип
unsigned int8 System.Byte Хранит беззнаковое 8-битное целочисленное значение
unsigned int16 System.UInt16 Хранит беззнаковое 16-битное целочисленное значение
unsigned int32 System.UInt32 Хранит беззнаковое 32-битное целочисленное значение
unsigned int64 System.UInt64 Хранит беззнаковое 64-битное целочисленное значение

Ниже мы рассмотрим типы и их подтипы более подробно, но прежде отметим, что в основе всех типов, как, впрочем, и в основе всей иерархии классов Microsoft .NET Framework, лежит класс System.Object. Для всех типов, которые будут рассмотрены ниже, этот класс, в частности, предоставляет методы, перечисленные в табл. 2.

Метод Описание
Equals Поддерживает сравнение объектов одного класса
Finalize Выполняет операции очистки памяти перед уничтожением объекта
GetHashCode Генерирует число, соответствующее значению, хранимому в объекте
ToString Возвращает строку, содержащую описание экземпляра класса
GetType Возвращает тип объекта

Далее мы сможем убедиться, что все типы так или иначе наследуют от System.Object. Начнем с данных со значениями.


Данные со значениями

Как мы отметили выше, к данным со значением относятся как встроенные типы так и определяемые пользователями. Все встроенные типы базируются на классе System.ValueType, который является непосредственным наследником System.Object. Каждый класс, реализующий встроенный тип, поддерживает определенный набор интерфейсов, которые используются для реализации тех или иных операций, а также уникальные для данного типа свойства и методы. Например, класс Boolean поддерживает интерфейсы IConvertible (для выполнения операций преобразования) и IComparable (для выполнения операций сравнения), а также содержит такие свойства, как FalseString и TrueString. Кроме того, класс Byte поддерживает интерфейсы IConvertible и IComparable, а также интерфейс IFormattable, используемый для преобразования значений в их строчное представление. Двигаясь дальше по списку наследников класса System. ValueType, мы находим класс Char, который поддерживает такие методы, как IsDigit, IsLetter, IsLetterOrDigit, IsNumber и т.п., существенно облегчающие работу с символами.

Классы, представляющие целочисленные типы — Int16, Int32, Int64, IntPtr, UInt16, UInt32, UInt64 и UIntPtr, содержат константы MinValue и MaxValue, задающие минимальное и максимальное число, которое может содержаться в данном типе, а также метод Parse, используемый для преобразования строки, состоящей из набора цифр, в соответствующий тип данных.

Типы с плавающей точкой — Single и Double — содержат свойства Epsilon (минимальное положительное число данного типа), MinValue (минимально допустимое число), MaxValue (максимально допустимое число), Nan (константа Not-A-Number, не число), NegativeInfinity (константа, описывающая отрицательную бесконечность) и PositiveInfinity (константа, описывающая положительную бесконечность), а также методы IsInfinity, IsNan, IsNegativeInfinity и IsPositiveInfinity, используемые для проверки хранимых в переменной данного типа значений.


Перечисления

Среди разнообразия типов, которые могут определять пользователи, отметим перечисления, создающиеся на базе класса System. Enum. Этот класс поддерживает интерфейсы IComparable, IFormattable и IConvertible, а также методы для получения имен констант (GetName, GetNames), получения значений (GetValues), определения типа элементов перечисления (GetUnderlyingType) и ряд других.

В следующем примере показано, как создать простое перечисление и воспользоваться методами GetNames и GetValues для получения списка имен всех его полей и их значений:

Module Module1  
      
    '  
    ' Геометрические фигуры  
    '  
    Public Enum Shapes  
        None      = 0  
        Circle    = 1  
        Rectangle = 2  
        Ellipse   = 3  
        Triangle  = 4  
    End Enum  
   
    Sub Main()  
   
        Dim GeoShapes As New Shapes()  
        Dim Names As String()  
        Dim Values() As Integer  
        Dim I As Integer  
        Names  = GeoShapes.GetNames(GeoShapes.GetType)  
        Values = GeoShapes.GetValues(GeoShapes.GetType)  
        Console.WriteLine()  
        For I = 0 To Names.GetUpperBound(0)  
            Console.WriteLine(vbTab & Names(I) & "=" & _  
             CType(Values(I), Integer).ToString("G"))  
        Next  
        Console.WriteLine()  
   
    End Sub  
End Module


Структуры

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

Рассмотрим небольшой пример. Создадим структуру TPoint, у которой будет два поля: целочисленные члены X и Y. В коде нашей программы, написанной на Visual Basic.NET, создадим переменную типа TPoint, инициализируем ее поля и выведем на экран их значения. Как это сделать, показано ниже:

Module Module1  
   
'  
' Структура TPoint содержит два целочисленных члена  
'  
    Structure TPoint  
        Public X As Integer  
        Public Y As Integer  
    End Structure  
   
    Sub Main()  
'  
' Переменная MyPoint – пользовательского типа  
'  
     Dim MyPoint As TPoint  
   
'   
' Инициализация переменной  
'  
        
      With MyPoint  
        .X = 100  
        .Y = 150  
'  
' Вывод значений   
'  
        Console.WriteLine(" X should be 100" & " X=" & .X)  
        Console.WriteLine(" Y should be 150" & " Y=" & .Y)  
      End With  
    End Sub  
End Module  

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

Dim MyPoint As TPoint  
Dim NewPoint  
   
 With MyPoint  
  .X = 100  
  .Y = 150  
 End With  
   
 NewPoint = MyPoint  
 With NewPoint  
  .X = 200  
  .Y = 50  
 End With  
 Console.WriteLine("NewPoint X, Y=" & NewPoint.X & ", " & NewPoint.Y)  
 Console.WriteLine("MyPoint  X, Y=" & MyPoint.X & ", " & MyPoint.Y)  
   
 End Sub  

По сравнению со структурами классы предоставляют большую гибкость. Мы рассмотрим классы в следующем разделе.

Завершая наше знакомство с данными со значениями, напомним, что они описывают значения, представляемые последовательностью байтов. Многие встроенные типы, перечисленные в табл. 1, относятся к этой группе. Данные со значениями часто располагаются на стеке — они могут быть локальными переменными, параметрами и значениями, возвращаемыми функциями. Таким образом, данные со значениями не должны занимать много места — в общем случае они занимают не более 12-16 байтов.


Ссылочные типы

Вторая группа типов в Common Type System — это ссылочные типы. Среди них есть объектные, интерфейсные и указательные типы. Рассмотрение ссылочных типов начнем с классов.

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


Классы

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

Продолжим наш пример. Теперь мы преобразуем созданную выше структуру в класс, который также будет иметь два целочисленных свойства. Для установки и получения значений этих свойств мы должны использовать ключевое слово Property и новые в VB.NET конструкции языка — Get/End Get и Set/End Set. Мы также создаем конструктор для нашего класса. Реализация класса TPoint показана ниже:

Imports System  
   
Module Module1  
   
'  
' Класс TPoint содержит два целочисленных свойства  
'  
    Public Class TPoint  
        Dim ptX As Integer       ' X  
        Dim ptY As Integer      ' Y  
'  
' Get и Set для свойства ptX  
'  
        Public Property X() As Integer  
            Get  
                Return ptX  
            End Get  
            Set(ByVal Value As Integer)  
                ptX = Value  
            End Set  
        End Property  
'  
' Get и Set для свойства ptY  
'  
        Public Property Y() As Integer  
            Get  
                Return ptY  
            End Get  
            Set(ByVal Value As Integer)  
                ptY = Value  
            End Set  
        End Property  
'  
' Конструктор  
'  
        Public Sub New()  
            ptX = 0  
            ptY = 0  
        End Sub  
    End Class  
   
    Sub Main()  
        Dim MyPoint As New TPoint()  
'   
' Инициализация объекта  
'  
        
      With MyPoint  
        .X = 100  
        .Y = 150  
'  
' Вывод значений   
'  
        Console.WriteLine(" X should be 100" & " X=" & .X)  
        Console.WriteLine(" Y should be 150" & " Y=" & .Y)  
      End With  
   
    End Sub  
   
End Module  

Здесь следует обратить внимание на то, что внутренние имена свойств класса (в нашем примере ptX и ptY) отличаются от имен, «видимых» вне класса (в нашем примере X и Y).


Методы

Методы служат для реализации функциональности классов. Рассмотрим это на примере. Расширим наш класс и реализуем метод SetXY, который будет устанавливать новые значения свойств X и Y. Для этого добавим в описание класса следующий код:

 Public Sub SetXY(ByVal newX As Integer, ByVal newY As Integer)  
  X = newX  
  Y = newY   
 End Sub  
и изменим код нашей программы:
 Sub Main()  
   Dim MyPoint As New TPoint()  
'   
' Инициализация объекта  
'  
        
   With MyPoint  
    .SetXY(100, 150)  
'  
' Вывод значений   
'  
    Console.WriteLine(" X should be 100" & " X=" & .X)  
    Console.WriteLine(" Y should be 150" & " Y=" & .Y)  
  End With  
   
 End Sub  

События

И наконец, последним элементом, который может содержаться в классах, создаваемых пользователями, является событие. Как было отмечено выше, события служат для асинхронных объявлений об изменениях в объектах. В нашем примере таким изменением в объекте будет задание новых значений свойств X и Y.

Реализацию события начнем с задания его имени, сопровождаемого ключевым словом Event. Далее в код, который является причиной возникновения события (в нашем примере это код, устанавливающий новые значения свойств), добавляем ключевое слово RaiseEvent и указываем название возникающего события:

Public Class TPoint  
    Dim ptX As Integer  ' X  
    Dim ptY As Integer  ' Y  
   
    Event PTChanged()  
   
    '  
    ' Get и Set для свойства ptX  
    '  
    Public Property X() As Integer  
        Get  
            Return ptX  
        End Get  
        Set(ByVal Value As Integer)  
            ptX = Value  
            RaiseEvent PTChanged()  
        End Set  
    End Property  
    '  
    ' Get и Set для свойства ptY  
    '  
    Public Property Y() As Integer  
        Get  
            Return ptY  
        End Get  
        Set(ByVal Value As Integer)  
            ptY = Value  
            RaiseEvent PTChanged()  
        End Set  
    End Property  
    '  
    ' Конструктор  
    '  
    Public Sub New()  
        ptX = 0  
        ptY = 0  
    End Sub  
    Public Sub SetXY(ByVal newX As Integer, ByVal newY As Integer)  
     X = newX  
     Y = newY   
    End Sub  
End Class  

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

Вот код клиентского приложения (для простоты класс TPoint реализован в отдельной библиотеке классов):

Imports ClassLibrary1  
Public Class Form1  
    Inherits System.Windows.Forms.Form  
   
    Dim WithEvents MyPoint As TPoint  
   
    Private Sub Button1_Click(ByVal sender As System.Object, _  
     ByVal e As System.EventArgs) Handles Button1.Click  
        MyPoint = New TPoint()  
    End Sub  
   
    Private Sub Panel1_MouseDown(ByVal sender As Object, _   
     ByVal e As System.Windows.Forms.MouseEventArgs) _  
     Handles Panel1.MouseDown  
        MyPoint.SetXY(e.X, e.Y)  
    End Sub  
   
    Private Sub MyPoint_PTChanged() Handles MyPoint.PTChanged  
        ListBox1.Items.Add(MyPoint.X & ", " & MyPoint.Y)  
    End Sub  
   
End Class  

Теперь объект MyPoint типа TPoint описан с использованием ключевого слова WithEvents. Это означает, что класс поддерживает события и мы можем создавать их обработчики. На рис. 2 показан пример работы нашей программы.

Обратите внимание на то, что в списке регистрируются парные координаты — X, Y, X, Y1, X1, Y1 и т.п. Это происходит из-за того, что событие PTChanged возникает и при изменении значения свойства X, и при изменении значения свойства Y. Таким образом, если одновременно изменяются два свойства, возникают два события. Чтобы исправить логику, достаточно удалить код, генерирующий события, из описаний свойств и добавить его в реализацию метода SetXY, как это показано ниже:

 Public Sub SetXY(ByVal newX As Integer, ByVal newY As Integer)  
    X = newX  
    Y = newY  
    RaiseEvent PTChanged()  
End Sub  

Делегаты

Говоря о событиях, следует упомянуть о делегатах — классе на базе System.Delegate, который содержит ссылку на метод. Таким образом, делегат — это указатель на функцию или косвенно-вызываемая функция. Чаще всего делегаты используются для описания обработчиков событий или для создания косвенно-вызываемых функций.

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

 Dim MyPoint As TPoint  
   
 Private Sub Button1_Click(ByVal sender As System.Object, _  
  ByVal e As System.EventArgs) Handles Button1.Click  
        MyPoint = New TPoint()  
        AddHandler MyPoint.PTChanged, AddressOf MyPoint_PTChanged  
 End Sub  
   
 Private Sub Panel1_MouseDown(ByVal sender As Object, _   
   ByVal e As System.Windows.Forms.MouseEventArgs) _  
   Handles Panel1.MouseDown  
     MyPoint.SetXY(e.X, e.Y)  
 End Sub  
   
 Private Sub MyPoint_PTChanged()  
    ListBox1.Items.Add(MyPoint.X & ", " & MyPoint.Y)  
 End Sub  

Такой подход позволяет нам создавать обработчики событий для более чем одного события, динамически переключать и отключать обработчики событий и т.п.


Массивы

Массивы задаются описанием типа элементов, числа размерностей, и нижней и верхней границ каждой размерности и могут содержать только данные указанного типа. Каждый элемент массива — это объект. массив базируется на классе System.Array, описывающем базовую функциональность массивов. Этот класс поддерживает такие интерфейсы, как ICloneable (реализует возможность создания еще одного экземпляра класса со значениями существующего экземпляра), IList (реализует возможность индивидуальной индексации коллекции объектов), ICollection (реализует возможность задания размеров, создания перечислителей и методов синхронизации) и IEnumerable (поддерживает итерацию по элементам коллекции). Ниже приведены базовые свойства массивов (табл. 3)

Свойство Описание
IsFixedSize Позволяет узнать, является ли массив массивом фиксированного размера
IsReadOnly Позволяет узнать, является ли массив массивом только для чтения
IsSynchronized Позволяет узнать, является ли доступ к массиву синхронизированным
Length Возвращает общее число элементов во всех размерностях массива
Rank Возвращает число размерностей массива
SyncRoot Возвращает объект, используемый для синхронизации доступа к массиву

и методы (табл. 4), поддерживаемые массивами.

Метод Описание
BinarySearch Выполняет поиск в одномерном массиве, используя алгоритм бинарного поиска
Clear Обнуляет указанные элементы массива
Copy Копирует указанные элементы массива в другой массив и при необходимости выполняет преобразование типов
IndexOf Возвращает первый индекс указанного элемента в одномерном массиве
LastIndexOf Возвращает последний индекс указанного элемента в одномерном массиве
Reverse Изменяет порядок следования элементов одномерного массива на противоположный
Sort Сортирует элементы одномерного массива
CopyTo Копирует все элементы одномерного массива в указанный одномерный массив, начиная с указанного индекса в принимающем массиве
Clone Создает точную копию массива
GetEnumerator Возвращает интерфейс IEnumerator для данного массива
GetLength Возвращает число элементов в указанной размерности массива
GetLowerBound Возвращает нижний индекс массива
GetUpperBound Возвращает верхний индекс массива
GetValue Возвращает значения указанных элементов массива
SetValue Устанавливает значения указанных элементов массива

В следующем примере показаны некоторые базовые операции с массивами:

    Sub Main()  
        Dim IntArray() As Integer = {0, 1, 2, 3, 4, 5}  
   
        With IntArray  
            Console.WriteLine(vbTab & "Type        = " & _  
              .GetType.ToString)  
            Console.WriteLine(vbTab & "IsFixedSize = " & .IsFixedSize)  
            Console.WriteLine(vbTab & "Length      = " & .Length)  
            Console.WriteLine(vbTab & "Rank        = " & .Rank)  
            Console.WriteLine(vbTab & "LowerBound  = " & _  
              .GetLowerBound(0))  
            Console.WriteLine(vbTab & "UpperBound  = " & _  
              .GetUpperBound(0))  
        End With  
          
    End Sub  

Ниже показано, как использовать методы GetValue и SetValue для получения значений элементов массива и изменения этих значений:

Console.WriteLine(vbCrLf & "Original Array:")  
 For I = .GetLowerBound(0) To .GetUpperBound(0)  
  Console.WriteLine(vbTab & "Array(" & I & ")" & " = " & .GetValue(I))  
  .SetValue(.GetValue(I) * 10, I)  
 Next  
   
Console.WriteLine(vbCrLf & "Modified Array:")  
 For I = .GetLowerBound(0) To .GetUpperBound(0)  
  Console.WriteLine(vbTab & "Array(" & I & ")" & " = " & .GetValue(I))  
Next  

Интерфейсы

Интерфейсы служат для описания функциональности, которая должна быть реализована тем или иным классом, но они не содержат кода, реализующего данную функциональность. Поскольку интерфейс не содержит кода, его нельзя унаследовать — вместо этого вы наследуете класс, реализующий тот или иной интерфейс.

Интерфейсы широко используются в библиотеке классов Microsoft .NET. Мы уже приводили несколько примеров классов, в которых реализуются такие интерфейсы, как IConvertible (для выполнения операций преобразования) и IComparable (для выполнения операций сравнения)). Полный список интерфейсов, определенных в библиотеке классов Microsoft .NET, представлен в документации к Microsoft .NET Framework SDK.


Указатели

Common Language Runtime поддерживает три типа указателей. К первому типу относятся управляемые указатели (managed poiters), генерируемые для аргументов методов, которые передаются по ссылке. Это единственный тип указателей, совместимый со спецификацией Common Language Runtime. К двум другим типам относятся неуправляемые указатели (unmanaged pointers) и неуправляемые указатели на функции (unmanaged function pointers). Так как неуправляемые указатели не совместимы с Common Language Runtime, их реализация и поддержка зависят от выбранного языка программирования.

Common Language Runtime поддерживает две операции над управляемыми указателями: получение значения, хранимого по указателю, и запись значения по адресу указателя. Отметим, что хотя указатели являются ссылочными типами, значение типа «указатель» не является объектом, а следовательно, определить точный тип такого значения невозможно.


Заключение

Мы ознакомились с одним из основных компонентов Microsoft .NET Framework — средой выполнения Common Language Runtime, рассмотрели такие темы, как исполняемые файлы и метаданные, кратко поговорили о Microsoft Intermediate Language (MSIL), Just-In-Time Compiler, узнали о назначении сборок и глобального кэша сборок (Global Assembly Cache). Затем мы подробно рассмотрели систему типов Common Type System и основные группы типов — данные со значениями и ссылочные типы. Отметим, что поддержка типов на уровне Common Language Runtime обеспечивает простую интеграцию кода, написанного на разных языках программирования. Вопрос о выборе языка программирования — будь то Visual Basic .NET, C# или какой-либо другой — не является первостепенным, поскольку все языки, поддерживающие спецификацию Common Language Runtime, обеспечивают доступ к рассмотренным нами типам. Вопрос лишь в синтаксических особенностях того или иного языка.

Проиллюстрируем вышесказанное. Рассказывая о классах, свойствах, методах и событиях, мы создали VB.NET-класс, реализующий объект TPoint, с двумя свойствами — X и Y и методом SetXY, который позволяет изменять значения этих свойств. При изменении значений свойств X и Y возникает событие PTChanged. Создадим клиентское приложение на C#, которое будет использовать наш VB.NET-класс, и в нем реализуем обработчик события PTChanged. Ниже приведен фрагмент кода, иллюстрирующий необходимые действия:

public class Form1 : System.Windows.Forms.Form  
{  
...  
      private ClassLibrary1.TPoint MyPoint;  
   
      public Form1()  
      {  
...  
   
      this.MyPoint = new ClassLibrary1.TPoint();  
      MyPoint.PTChanged +=   
        new System.EventHandler(this.MyPoint_PTChanged);                  
        
      }  
   
...  
   
      private void button1_Click(object sender, System.EventArgs e)  
            {  
                  MyPoint.SetXY(10, 150);  
            }  
      private void button2_Click(object sender, System.EventArgs e)  
            {  
                  MyPoint.SetXY(100, 250);  
            }  
   
      private void button3_Click(object sender, System.EventArgs e)  
            {  
                  MyPoint.SetXY(50, 100);  
            }  
      void MyPoint_PTChanged(object sender, System.EventArgs e)   
            {  
            MessageBox.Show("X=" + MyPoint.X.ToString("G") +   
              ", Y=" + MyPoint.Y.ToString("G"),   
              "Changed", MessageBoxButtons.OK);  
            }  
      }  
}  

В данном случае необходимо лишь создать Windows-приложение на C#, подключить ссылку на библиотеку классов, в которой описан класс, реализующий объект TPoint, и описать объект типа TPoint:

private ClassLibrary1.TPoint MyPoint;

Теперь вызовем конструктор объекта TPoint и опишем новый обработчик событий:

this.MyPoint = new ClassLibrary1.TPoint();
MyPoint.PTChanged += new
System.EventHandler(this.MyPoint_PTChanged);

Сам обработчик событий реализован в следующем методе:

void MyPoint_PTChanged(object sender, System.EventArgs e)   
      {  
      MessageBox.Show(  
        "X=" + MyPoint.X.ToString("G") + ", Y=" +   
               MyPoint.Y.ToString("G"),   
        "Changed", MessageBoxButtons.OK);  
      }  

Те, кто когда-либо пробовал использовать в Visual Basic библиотеки для C или интегрировать код на Delphi с кодом на VB, смогут по достоинству оценить изменения, привнесенные Common Language Runtime.

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

© Станислав Митичкин
www.mista.ru
, 1997-2003
1C:TOP-100
Волшебный форум