« Поставить закладку » « Сделать стартовой »

« Форумы » « Блоги » « Статьи » « Новости » « Файлы » « Realcoding IRC » « Site map » « Поиск »


Главная Главная
Анонсы Анонсы
Форумы Форумы
Каталог Каталог
Поиск Поиск
Опросы Опросы
Книжный магазин Книжный магазин
Реклама на сайте
Публикации Публикации
Партнеры Партнеры
Карта Карта сайта
Рассылки Рассылки
RSS экспорт
Настройки Настройки
О нас пишут О нас пишут
Контакты Контакты
Гостевая книга Гостевая книга

Тестирование 64-битных приложений

ПнВтСрЧтПтСбВс
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30          
    Популярное
Взаимодействие нескольких форм

Функция AccessResource

Бан по IP-адресу средствами PHP

Фильтрация и преобразование цифровых фотографий

Немодальный режим работы

Освоение Ajax, Часть 1: Введение в Ajax

Автозапуск программы в C#

Вывод

Выражения и Операторы

Chapter 7. Инициализация или как написать приложение с нуля




    Архив файлов



    Сообщества



    Документация

Статьи:: .NET Framework :: Часть 3. Библиотека классов


отправить ссылку другу версия для печати  Обсудить на форуме

Часть 3. Библиотека классов





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

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

Библиотека классов .NET Framework Class Library содержит классы, обеспечивающие следующие функции:

            поддержку базовых и определяемых пользователями типов;

            поддержку обработки исключительных ситуаций;

            операции ввода/вывода и работу с потоками;

            обращение к функциям операционной системы;

            доступ к данным;

            возможность создания Windows-приложений;

            возможность создания клиентских и серверных Web-приложений;

            возможность создания Web-сервисов.

Все классы, реализованные в .NET Framework Class Library организованы в виде пространств имен (namespaces). Каждое пространство имен содержит классы и другие типы, которые относятся к специфическим задачам или группе задач — операциям ввода/вывода, созданию Web-приложений, работе с данными и XML-документами и т.п. В таблице показаны наиболее важные пространства имен в библиотеке классов .NET.

После краткого обзора основных пространств имен мы готовы приступить к более детальному рассмотрению библиотеки классов .NET. Первая остановка в нашем путешествии будет не совсем обычной — вместо традиционного рассмотрения базового класса Object, который служит предком всех классов в библиотеке классов .NET, мы рассмотрим класс Console и консольные приложения. Почему мы поступаем именно так, будет понятно чуть позже.

Класс Console и консольные приложения

Используя класс System.Console, мы можем создавать простейшие приложения для среды .NET — консольные приложения, которые используют системное окно для ввода и вывода информации и не требуют графического интерфейса. Так как большинство примеров в данном цикле будет использовать консольные приложения, мы начнем наше знакомство с библиотекой классов с класса Console.

Класс Console представляет собой стандартные потоки ввода, вывода и сообщений об ошибках. Приложения, использующие данный класс, могут читать символы из стандартного потока ввода (input stream) и выводить символы в стандартный поток вывода (output stream). Ошибки выводятся в стандартный поток сообщений об ошибках (error output stream). Эти три потока автоматически ассоциируются с консолью при запуске приложения и могут быть определены через свойства In, Out и Error класса Console. По умолчанию стандартный поток ввода — это объект типа System.IO.TextReader, а потоки вывода и сообщений об ошибках — объекты типа System.IO. TextWriter. При необходимости мы можем переопределить эти потоки в файловые потоки, сетевые потоки, потоки в памяти и т.п.

Используя Visual Basic .NET, мы создаем консольное приложение как новый модуль, который содержит подпрограмму с именем Main — она является точкой входа в наше консольное приложение:

·  '---------------------------------------
' .NET – Консольное приложение
'---------------------------------------
Imports System
Module Cons

Sub Main()
    Console.WriteLine(".NET Console application")
    Console.ReadLine()
End Sub

End Module

Методы Read и ReadLine служат для чтения одного или более символов или символа новой строки из стандартного потока ввода, а методы Write и WriteLine — для вывода одного или более символов либо строки с символом новой строки в стандартный поток вывода.

Методы SetIn, SetOut и SetError позволяют переопределить стандартные потоки ввода, вывода и ошибок. Эти методы ожидают аргумент типа TextWriter, который описывает поток.

Теперь мы полностью готовы начать изучение Microsoft .NET Class Library. В следующем разделе мы рассмотрим пространство имен System и его дочерние пространства имен.

Пространство имен System

Пространство имен System является корневым пространством имен в Microsoft .NET Class Library и содержит фундаментальные типы данных, реализованные в .NET Framework. Это пространство имен содержит класс Object, который служит предком для всех классов в библиотеке классов .NET, примитивные и расширенные типы, а также более 100 дополнительных классов, используемых для обработки исключительных ситуаций, управления доменами приложений, сборки мусора и т.п.

Класс Object

Класс System.Object служит предком для всех классов в библиотеке классов .NET. Методы, реализованные в данном классе, показаны на следующем рисунке.

Кратко рассмотрим каждый из этих методов:

            Метод Equals (Object) или Equals (Object, Object) — служит для проверки, являются ли два объекта одним и тем же экземпляром. Для данных со значениями этот метод переопределен (в классе ValueType) и позволяет проверить идентичность хранимых экземплярами объекта значений. Обратите внимание: когда мы сравниваем два ссылочных типа, метод Equals проверяет, являются ли оба экземпляра идентичными; для данных со значениями метод Equals также проверяет идентичность данных, хранимых экземплярами объекта.

            Метод ReferenceEquals (Object, Object) проверяет, являются ли два объекта одним и тем же экземпляром класса.

            Метод Finalize() по умолчанию не выполняет никаких действий. Этот метод может быть переопределен в унаследованных классах для выполнения финальной очистки памяти перед тем, как механизм сборки мусора (Garbage Collector) уничтожит данный объект.

            Метод GetHashCode() служит для генерации хэш-значений (типа Integer), которые могут быть использованы для хранения объектов в хэш-таблицах.

            Метод MemberwiseClone() создает точную копию объекта.

            Метод ToString() возвращает текстовое представление объекта. В большинстве случаев этот метод возвращает полное имя класса для данного объекта.

            Метод GetType() возвращает объект типа Type для данного экземпляра класса.

Ниже мы расскажем, как используется класс Type.

Класс Type и пространство имен Reflection

Класс Type является нашей точкой входа в пространство имен Reflection. Отражение (Reflection) в терминах .NET — это способность изучать возможности классов во время выполнения программы. Используя отражения, мы можем извлекать классы, изучать их методы, свойства, конструкторы, поля, события и другие члены, одним словом, получаем доступ к метаданным, ассоциированным с данным классом.

Класс Type содержит методы типа GetMethods() и GetProperties(), которые могут использоваться для получения информации о членах класса. Используя классы, реализованные в пространстве имен Reflection, мы можем получать сведения, например, о параметрах методов (используя класс System.Reflection. MethodInfo) и даже вызывать методы с помощью метода Invoke().

В следующем примере показано, как начать использовать механизм отражений. Приведенный ниже код показывает, как с помощью метода GetType() получить объект Type и каким образом можно применять ряд свойств этого объекта:

·  '-------------------------------------------
' .NET Пример использования метода GetType
'-------------------------------------------

Imports System
Imports System.Reflection

Module Cons

    Sub Main()
        Dim I As Integer
        Dim T As Type
        T = I.GetType()
        Console.WriteLine("Name = " & T.Name)
        Console.WriteLine("Module = " & T.Module.ToString())
        Console.WriteLine("Namespace = " & T.Namespace)
    End Sub

End Module

Кратко рассмотрим основные возможности, предоставляемые пространством имен Reflection, а затем проиллюстрируем некоторые из них примерами.

            Класс Assembly можно использовать для определения и загрузки сборок, загрузки модулей из манифеста сборки (assembly manifest), поиска типов, описанных в сборке, и создания экземпляров этих типов.

            Класс Module можно использовать для поиска классов в модуле, а также всех глобальных и локальных методов, определенных в данном модуле.

            Класс ConstructorInfo можно использовать для поиска имен, параметров, модификаторов доступа и другой информации о конструкторе. Поиск и вызов конструкторов мы можем осуществлять с помощью методов GetConstructors() или GetConstructor() объекта Type.

            Класс MethodInfo используется для поиска имен, возвращаемых типов, параметров, модификаторов доступа и другой информации о методе. Поиск и вызов методов мы можем осуществлять с помощью методов GetMethods() или GetMethod() объекта Type.

            Для поиска информации о полях — именах, модификаторах доступа и т.п. — используется класс FieldInfo. Кроме того, с помощью данного класса мы можем получать и задавать значения полей.

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

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

            Класс ParameterInfo используется для поиска информации о параметрах — названии, типе данных, и т.п.

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

·  '-------------------------------------------
' .NET – Пример использования "отражений"
'-------------------------------------------

Imports System
Imports System.Reflection

Module Cons

    Sub Main()
        Dim I As Integer
        Dim T As Type
        Dim Types() As Type
        Dim M As [Module]
        T = I.GetType()
        M = T.Module
        Types = M.GetTypes()
        For Each T In Types
            Console.WriteLine(T.FullName)
        Next
    End Sub

End Module

Ниже показана выводимая данным кодом информация:

Как видно из вышеприведенного списка, в целом концепция отражений напоминает использование интерфейса ITypeLibrary в Win32 API для исследования библиотек типов, но версия для .NET предоставляет больше возможностей, более проста в использовании и более дружественна к различным языкам программирования.

Теперь расширим наш пример и добавим информацию о свойствах, конструкторах, методах, интерфейсах и событиях. Для этого воспользуемся методами GetProperties(), GetConstructors(), GetMethods(), GetInterfaces() и GetEvents() объекта Type. Каждый из этих методов возвращает массив элементов типа PropertyInfo, MethodInfo, EventInfo и т.п. — каждый тип наследует от абстрактного типа MemberInfo, который мы и используем в нашем примере. Исключение составляет только тип PropertyInfo — этот тип используется для того, чтобы получить дополнительную информацию о свойствах:

·  '-------------------------------------------
' .NET – Пример использования "отражений"
'-------------------------------------------

Imports System
Imports System.Reflection
Module Cons

    Sub Main()
        Dim T As Type
        Dim MI As MemberInfo
        Dim Types() As Type
        Dim Members() As MemberInfo
        Dim M As [Module]
        Dim PI As PropertyInfo
        Dim PText As String
        T = Type.GetType("System.Array")
        Console.WriteLine("{0} : {1}", GetTypeDescription(T), T)
        '
        ' Показать все свойства
        '
        Console.WriteLine("---- Свойства ----")
        Members = T.GetProperties
        For Each MI In Members
            PI = MI
            If PI.CanRead And PI.CanWrite Then
                PText = "get; set;"
            Else
                If PI.CanRead Then
                    PText = "get"
                Else
                    If PI.CanWrite Then
                        PText = "set"
                    End If
                End If
            End If
            Console.WriteLine("{0} {1} : {2} {3}", vbTab, "Prop", _
                            PText, MI.ToString)
        Next
        '
        ' Показать все конструкторы
        '
        Console.WriteLine("---- Конструкторы ----")
        Members = T.GetConstructors(BindingFlags.Public Or _
              BindingFlags.Static Or BindingFlags.NonPublic Or _
              BindingFlags.Instance)
        For Each MI In Members
            Console.WriteLine("{0} {1} : {2}", vbTab, "Meth",MI.ToString)
        Next
        '
        ' Показать все методы
        '
        Console.WriteLine("---- Методы ----")
        Members = T.GetMethods
        For Each MI In Members
            Console.WriteLine("{0} {1} : {2}", vbTab, "Meth", MI)
        Next
        '
        ' Показать все интерфейсы
        '
        Console.WriteLine("---- Интерфейсы ----")
        Members = T.GetInterfaces
        For Each MI In Members
            Console.WriteLine("{0} {1} : {2}", vbTab, "Intf", _
              MI.ToString)
        Next
        '
        ' Показать все события
        '
        Console.WriteLine("---- События ----")
        Members = T.GetEvents
        For Each MI In Members
            Console.WriteLine("{0} {1} : {2}", vbTab, "Evnt", _
              MI.ToString)
        Next
    Next
End Sub

Private Function GetTypeDescription(ByVal aType As Type) As String
    Dim str As String = Nothing
    If aType.IsClass Then
        str = "Class"
    End If
    If aType.IsInterface Then
        str = "Interface"
    End If
    If aType.IsValueType Then
        str = "Struct"
    End If
    If aType.IsArray Then
        str = "Array"
    End If
    Return str
End Function 'GetTypeDescription

End Module

Ниже показана информация, выводимая нашим примером для класса System.Array:

·  Class : System.Array
---- Свойства ----
    Prop : get Int32 Length
    Prop : get Int32 Rank
    Prop : get System.Object SyncRoot
    Prop : get Boolean IsReadOnly
    Prop : get Boolean IsFixedSize
    Prop : get Boolean IsSynchronized
---- Конструкторы ----
    Meth : Void .ctor()
---- Методы ----
    Meth : System.Collections.IEnumerator GetEnumerator()
    Meth : Boolean get_IsSynchronized()
    Meth : System.Object get_SyncRoot()
    Meth : Void CopyTo(System.Array, Int32)
    Meth : Boolean get_IsFixedSize()
    Meth : Boolean get_IsReadOnly()
    Meth : System.Object Clone()
    Meth : Int32 GetHashCode()
    Meth : Boolean Equals(System.Object)
    Meth : System.String ToString()
    Meth : System.Array CreateInstance(System.Type, Int32)
    Meth : System.Array CreateInstance(System.Type, Int32, Int32)
    Meth : System.Array CreateInstance(System.Type, Int32, Int32, Int32)
    Meth : System.Array CreateInstance(System.Type, Int32[])
    Meth : System.Array CreateInstance(System.Type, Int32[], Int32[])
    Meth : Void Copy(System.Array, System.Array, Int32)
    Meth : Void Copy(System.Array, Int32, System.Array, Int32, Int32)
    Meth : Void Clear(System.Array, Int32, Int32)
    Meth : System.Object GetValue(Int32[])
    Meth : System.Object GetValue(Int32)
    Meth : System.Object GetValue(Int32, Int32)
    Meth : System.Object GetValue(Int32, Int32, Int32)
    Meth : Void SetValue(System.Object, Int32)
    Meth : Void SetValue(System.Object, Int32, Int32)
    Meth : Void SetValue(System.Object, Int32, Int32, Int32)
    Meth : Void SetValue(System.Object, Int32[])
    Meth : Int32 get_Length()
    Meth : Int32 GetLength(Int32)
    Meth : Int32 get_Rank()
    Meth : Int32 GetUpperBound(Int32)
    Meth : Int32 GetLowerBound(Int32)
    Meth : Int32 BinarySearch(System.Array, System.Object)
    Meth : Int32 BinarySearch(System.Array, Int32, Int32, System.Object)
    Meth : Int32 BinarySearch(System.Array, System.Object,
        System.Collections.IComparer)
    Meth : Int32 BinarySearch(System.Array, Int32, Int32, System.Object,
        System.Collections.IComparer)
    Meth : Int32 IndexOf(System.Array, System.Object)
    Meth : Int32 IndexOf(System.Array, System.Object, Int32)
    Meth : Int32 IndexOf(System.Array, System.Object, Int32, Int32)
    Meth : Int32 LastIndexOf(System.Array, System.Object)
    Meth : Int32 LastIndexOf(System.Array, System.Object, Int32)
    Meth : Int32 LastIndexOf(System.Array, System.Object, Int32, Int32)
    Meth : Void Reverse(System.Array)
    Meth : Void Reverse(System.Array, Int32, Int32)
    Meth : Void Sort(System.Array)
    Meth : Void Sort(System.Array, System.Array)
    Meth : Void Sort(System.Array, Int32, Int32)
    Meth : Void Sort(System.Array, System.Array, Int32, Int32)
    Meth : Void Sort(System.Array, System.Collections.IComparer)
    Meth : Void Sort(System.Array, System.Array,         System.Collections.IComparer)
    Meth : Void Sort(System.Array, Int32, Int32,         System.Collections.IComparer)
    Meth : Void Sort(System.Array, System.Array, Int32, Int32,
        System.Collections.IComparer)
    Meth : Void Initialize()
    Meth : System.Type GetType()
---- Интерфейсы ----
    Intf : System.ICloneable
    Intf : System.Collections.IList
    Intf : System.Collections.ICollection
    Intf : System.Collections.IEnumerable

Обратите внимание на то, что параметры методов не имеют названийв листинге показаны только типы данных. Чтобы получить более подробную информацию о параметрах методов, мы должны воспользоваться методом GetParameters() и структурой ParameterInfo. Как это сделать, показано ниже:

·  '
' Показать все методы
'
Console.WriteLine("---- Методы ----")
Members = T.GetMethods
For Each MI In Members
    PAInfo = CType(MI, MethodInfo).GetParameters
    If PAInfo.Length > 0 Then
       Console.WriteLine("{0} {1} : {2}{3}", vbTab, "Meth", MI.Name, "(")
       For Each PAI In PAInfo
           Console.WriteLine(" {0} {1} : {2}", vbTab, PAI.Name, _
               PAI.ParameterType.ToString)
       Next
       Console.WriteLine("{0}{1}", vbTab, ")")
    Else
        Console.WriteLine(" {0} {1} : {2}{3}", vbTab, "Meth", MI.Name, _
            "()")
    End If
Next

Теперь мы знаем названия параметров и их тип:

·  ---- Методы ----
               Meth : GetEnumerator()
               Meth : get_IsSynchronized()
               Meth : get_SyncRoot()
               Meth : CopyTo(
               array : System.Array
               index : System.Int32
               )
               Meth : get_IsFixedSize()
               Meth : get_IsReadOnly()
               Meth : Clone()
               Meth : GetHashCode()
               Meth : Equals(
               obj : System.Object
               )
               Meth : ToString()
               Meth : CreateInstance(
               elementType : System.Type
               length : System.Int32
               )

...

Для того чтобы получить доступ к сборке (в нашем примере мы использовали сборку по умолчанию (— mscorlib.dll), всегда загруженную в память), надо обратиться к этой сборке. Вот как это сделать:

·  Imports System.Reflection
Imports System.IO
Imports Microsoft.Win32
Imports Microsoft.VisualBasic

Module Module1

    Sub Main()
        Dim Asm As [Assembly]
        Dim Mdls As [Module]()
        Dim Mdl As [Module]
        Asm = [Assembly].LoadFrom(GetNetFrameworkPath() + _
            system.windows.forms.dll")
        Mdls = Asm.GetModules
        Mdl = Mdls(0)
    End Sub

    Function GetNetFrameworkPath() As String
        Registry.LocalMachine.OpenSubKey( _             "SOFTWAREMicrosoft.NETFramework")
        GetNetFrameworkPath = CType(Key.GetValue("InstallRoot"), _
            String) + CType(Key.GetValue("Version"), String) + ""
    End Function

End Module

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

В следующем номере мы продолжим знакомство с библиотекой классов .NET Framework Class Library. Мы рассмотрим массивы (класс System.Array) и коллекции (пространство имен System.Collections).




Рубрика: .NET Framework




Инструменты Internet Explorer 8 Beta 2 для разработчиков.

Вебмастеру

В марте этого года мы уже писали об инструментах для разработчика в IE8 Beta 1, но IE8 Beta2 позволяет более полно использовать инструменты за счет значительных изменений в имеющихся функциях, а также новых возможностей. В принципе инструменты для разработчика должны обладать следующими свойствами: Быть интегрированными и простыми в использовании; Иметь визуальный интерфейсC их помощью можно быстро протестировать сайт.


Подробнее... | Рубрика: Вебмастеру | Добавлено: 05.09.2008

Google Developer Day 2008 в Москве.

Мероприятия

Дата проведения: 28 октября 2008 г.; Место проведения: Амбер Плаза, Москва, Россия. Конференция для веб-разработчиков и разработчиков мобильных приложений в Москве. Узнайте, как наилучшим образом использовать инструменты разработки и API от Google, чтобы создавать социальные, мобильные и картографические приложения, как использовать AJAX/JavaScript инструменты и библиотеки от Google и многое другое из первых уст.


Подробнее... | Рубрика: Мероприятия | Добавлено: 05.09.2008

ТОП 10 самых раздражающих факторов для программиста.

Разное

Совсем недавно наткнулся в интернете на забавный "хит-парад" наиболее раздражающих вещей для программиста. Поскольку он был на английском — решил перевести текст и несколько адаптировать к нашим реалиям…


Подробнее... | Рубрика: Разное | Добавлено: 03.09.2008

Остальные статьи:

Windows Server 7, 8 и 9
jQuery для JavaScript-программистов
Инновационный веб-броузер Google Chrome стартует уже сегодня
Windows 7: подход к производительности системы
Trac + Subversion @ Ubuntu: Revisited
[g]Vim в режиме Python: Рекомпиляция в Windows
Java + JSON. Пути к дружбе
Драйвер SQL Server 2005 для PHP
Типы данных в MySQL (сжатый справочник для PHP программиста)
PHP класс для работы с Яндекс.XML
Ошибки начинающих PHP разработчиков
Наследование шаблонов в Smarty
Особенности хранения сессий PHP в memcached
Internet Explorer 8 beta 2
9 правил для начинающего Ajax-разработчика
ExtJS 2.2 - полная поддержка Firefox 3, новые виджеты и другие нововведения


Цитата дня (все,добавить):



    Рубрикатор

Программирование

C/С++
Обучение
Windows API
XAML
Моделирование
Паттерны
Visual Basic 7 .NET
WxWidgets
Функции WinApi
Функции С++
Разработка под Mac OS
Eiffel
Visual Studio 2008
UI дизайн
Алгоритмы
Конкурсные статьи
Turbo Pascal
Visual Studio
CASE-средства
Visual Studio 2005
Без VCL
Delphi
Тех. документация
Тестирование
Software Testing
ООП
TCP/IP
Google Android
Windows Installer
.NET Framework
Драйвера
C# C Sharp
Справка
Проектирование
Информ. системы
Visual Basic
Assembler
Оптимизация кода
Gtk+
Компоненты
Реинжиниринг
Управление проектами
Extreeme programming
Lotus Notes
Алгебраическое проектирование

Интернет технологии

PHP
Perl
ASP
WAP
Cookies
SSI
CGI
Web Servers
VB Script
DNS
CSS
XML
Html
Java Script
Java2ME
Firewall
Flash
.htaccess
Apache
VRML
Протоколы
Поисковые системы
Технология JAVA
Учебник по PHP
Учебник по JavaScript
Учебник по XML
Java Q&A
AJAX
DHTML
XHTML
Dreamweaver
Web 2.0
Python
Вебмастеру
Cisco
Ruby on Rails
Silverlight

Базы данных

Access
InterBase
MySQL
Oracle
ADO .NET
Основы SQL
Учебник по Access 2002
MS
Microsoft FoxPro
Доступ к данным
XML в MS SQL Server 2000
ODBC и MyODBC
Обучение
Caché
DB2
PostgresSQL
Sybase
Теория
Хранилища данных
Безопасность
Реляционные данные
MySQL и mSQL

Остальное:

Разное
Обзоры книг
Безопасность
Графика и дизайн
Юмор
Linux
Фракталы
Microsoft Axapta
Многоядерность
Сети
Microsoft Office
Работа
MS-DOS
Криптография
Графика и игроделание
Новости SDK
Системы защиты
Учебник по AutoCad
CVS
Windows XP
Windows Server 2003
Windows Vista
Windows 7
Мероприятия

    Кто на сайте
Вы не зарегистрированы.
Имя:

Пароль:

Запомнить

Регистрация позволит Вам пользоваться дополнительными сервисами.
Сейчас на сайте:
Гостей: 72
Пользователей: 0