- •1. Язык программирования c# 3
- •2. Базовые элементы .Net Framework 67
- •3. ТЕхнология .Net Remoting 144
- •Введение
- •1. Язык программирования c#
- •1.1. Платформа .Net – обзор архитектуры
- •1.2. Язык c# - общие концепции синтаксиса
- •1.3. Система типов языка c#
- •1.4. Преобразования типов
- •1.5. Идентификаторы, ключевые слова и литералы
- •1.6. Объявление переменных, полей и констант
- •1.7. Выражения и операции
- •1.8. Операторы языка c#
- •1.9. Объявление и вызов методов
- •1.10. Массивы в c#
- •1.11. Работа с символами и строками в c#
- •1.12. Синтаксис объявления класса, Поля и методы класса
- •1.13. Свойства и индексаторы
- •1.14. Конструкторы класса и Жизненный цикл объекта
- •1.15. Наследование классов
- •1.16. Перегрузка операЦий
- •1.17. Делегаты
- •1.18. События
- •1.19. Интерфейсы
- •1.20. Структуры и перечисления
- •1.21. Пространства имен
- •1.22. Генерация и обработка исключительных ситуаций
- •1.23. Нововведения в языке c# 2.0
- •1.24. Обобщенные типы (generics)
- •2. Базовые элементы .Net Framework
- •2.1. Метаданные и механизм отражения
- •2.2. Пользовательские и встроенные атрибуты
- •2.3. Пространство имен system.Collections
- •2.4. Работа с файлами и директориями
- •2.5. Использование потоков данных
- •2.6. Сериализация
- •2.7. Сериализация объектов в нестандартном формате
- •2.8. Введение в xml
- •2.9. Работа с xml-документами в .Net framework
- •2.10. МНогопоточное программирование
- •2.11. Синхронизация потоков
- •2.12. Асинхронный вызов методов
- •2.13. Состав и взаимодействие сборок
- •2.14. Конфигурирование сборок
- •3. ТЕхнология .Net Remoting
- •3.1. Домены приложений
- •3.2. Архитектура .Net Remoting
- •3.3. Активация удаленных объектов и их время жизни
- •3.4. Программная настройка Remoting
- •3.5. Удаленные Объекты с клиентской активацией
- •3.6. Настройка Remoting при помощи конфигурационных файлов
- •3.7. Хостинг распределенных приложений
- •3.8. Объекты-сообщения
- •3.9. Пользовательские канальные приемники
- •4.1. Архитектура ado.Net
- •4.2. Учебная база cd Rent
- •4.3. Соединение с базой данных
- •4.4. Выполнение команд и запросов к базе данных
- •4.5. Чтение данных и объект DataReader
- •4.6. Параметризированные запросы
- •4.7. Рассоединенный набор данных
- •4.8. Заполнение Рассоединенного набора данных
- •4.9. Объект класса DataColumn – колонка таблицы
- •4.10. Объекты класса DataRow – строки таблицы
- •4.11. Работа с объектом класса DataTable
- •4.12. DataSet и схема рассоединенного набора данных
- •4.13. Типизированные DataSet
- •4.14. Поиск и фильтрация данных в DataSet
- •4.15. Класс DataView
- •4.16. СиНхронизация набора данных и базы
- •5.1. Архитектура и общие концепции asp.Net
- •5.2. Пример aspx-страницы. Структура страницы
- •5.3. Директивы страницы
- •5.4. Класс System.Web.Ui.Page. События страницы
- •5.5. Серверные элементы управления
- •5.6. Элементы управления Web Controls
- •5.7. Проверочные элементы управления
- •5.8. Списковые элементы управления
- •5.9. Связывание данных
- •5.11. Управление состояниями в web-приложениях
- •5.12. Кэширование
- •5.13. Безопасность в web-приложениях
- •5.14. Создание пользовательских элементов управления
- •Литература
1.10. Массивы в c#
Объявление массива в языке C# схоже с объявлением переменной, но после указания типа размещается пара квадратных скобок – признак массива:
int[] Data;
Массив является ссылочным типом, поэтому перед началом работы любой массив должен быть создан в памяти. Для этого используется ключевое слово new, после которого указывается тип массива и в квадратных скобках – количество элементов массива.
int[] Data;
Data = new int[10];
Созданный массив автоматически заполняется значениями по умолчанию своего базового типа. Создание массива можно совместить с его объявлением:
int[] Data = new int[10];
Для доступа к элементу массива указывается имя массива и индекс в квадратных скобках: Data[0] = 10.
Элементы массива нумеруются с нуля, в C# не предусмотрено синтаксических конструкций для указания особого значения нижней границы массива.
В языке C# существует способ инициализации массива значениями при создании. Для этого используется список элементов в фигурных скобках. Инициализация может быть выполнена в развернутой и короткой форме, которые эквивалентны:
int[] Data = new int[10] {1, 2, 3, 5, 7, 11, 13, 17, 19, 23};
int[] Data = {1, 2, 3, 5, 7, 11, 13, 17, 19, 23};
Если инициализация выполняется в развернутой форме, то количество элементов в фигурных скобках должно быть равно числу, указанному в квадратных скобках.
При необходимости можно объявить массивы, имеющие несколько размерностей. Для этого в квадратных скобках после типа массива помещают запятые, «разделяющие» размерности:
// объявлен двумерный массив D
int[,] D;
// создаем массив D так:
D = new int[10,2];
// объявим трехмерный Cube и создадим его
int[,,] Cube = new int[3,2,5];
// установим элемент массива Cube:
Cube[1,1,0] = 1000;
// объявим маленький двумерный массив и инициализируем его
int[,] C = new int[2,4] {
{1, 2, 3, 4},
{10, 20, 30, 40}
};
// то же самое, немного короче:
int[,] C = {{1, 2, 3, 4}, {10, 20, 30, 40}};
В приведенных примерах объявлялись массивы из нескольких размерностей. Такие массивы всегда являются прямоугольными. Можно объявить массив массивов, используя следующий синтаксис:
int[][] Table; // Table –массив одномерных массивов
Table = new int[3][]; // в Table будет 3 одномерных массива
Table[0] = new int[2]; // в первом будет 2 элемента
Table[1] = new int[20]; // во втором – 20 элементов
Table[2] = new int[12]; // в третьем – 12 элементов
// а вот так мы работаем с элементами массива Table:
Table[1][3] = 1000;
// совместим объявление и инициализацию массива массивов
int[][] T = {
new int[2] {10, 20},
new int[3] {1, 2, 3}
};
При работе с массивами можно использовать цикл foreach, перебирающий все элементы. В следующем фрагменте производится суммирование элементов массива Data:
int[] Data = {1,3,5,7,9};
int Sum = 0;
foreach(int element in Data)
Sum += element;
В цикле foreach возможно перемещение по массиву в одном направлении – от начала к концу, при этом попытки присвоить значение элементу массива игнорируются.
В качестве примера работы с массивами рассмотрим программу, выполняющую сортировку массива целых чисел.
using System;
class MainClass
{
public static void Main()
{
Console.Write("Введите число элементов: ");
int Size = Int32.Parse(Console.ReadLine());
int[] M = new int[Size];
for (int i = 0; i < Size; i++) {
Console.Write("Введите {0} элемент массива: ", i);
M[i] = Int32.Parse(Console.ReadLine());
}
Console.WriteLine("Исходный массив:");
foreach(int i in M) Console.Write("{0,6}", i);
Console.WriteLine();
for(int i = 0; i < Size-1; i++)
for(int j = i+1; j < Size; j++) {
if (M[i] > M[j]) {
int dop = M[i];
M[i] = M[j];
M[j] = dop;
}
}
Console.WriteLine("Отсортированный массив:");
foreach(int i in M) Console.Write("{0,6}", i);
}
}
Все массивы в .NET Framework могут рассматриваться как классы, являющиеся потомками класса System.Array. В табл. 3 описаны основные методы и свойства класса System.Array.
Таблица 3
Элементы класса System.Array
Имя элемента |
Описание |
Rank |
Свойство только для чтения, возвращает размерность массива |
Length |
Свойство только для чтения, возвращает число элементов массива |
GetLength() |
Метод возвращает число элементов в указанном измерении |
GetLowerBound() |
Метод возвращает нижнюю границу для указанного измерения |
GetUpperBound() |
Метод возвращает верхнюю границу для указанного измерения |
GetValue() |
Метод возвращает значение элемента с указанными индексами |
SetValue() |
Метод устанавливает значение элемента с указанными индексами (значение – первый аргумент). |
Sort() |
Статический метод, который сортирует массив, переданный в качестве параметра. Тип элемента массива должен реализовывать интерфейс IComparable |
BinarySearch() |
Статический метод поиска элемента в отсортированном массиве. Тип элемента массива должен реализовывать интерфейс IComparable |
IndexOf() |
Статический метод, возвращает индекс первого вхождения своего аргумента в одномерный массив или –1, если элемента в массиве нет |
LastIndexOf() |
Статический метод. Возвращает индекс последнего вхождения своего аргумента в одномерный массив или –1, если элемента в массиве нет |
Reverse() |
Статический метод, меняет порядок элементов в одномерном массиве или его части на противоположный |
Copy() |
Статический метод. Копирует раздел одного массива в другой массив, выполняя приведение типов |
Clear() |
Статический метод. Устанавливает для диапазона элементов массива значение по умолчанию для типов элементов |
CreateInstance() |
Статический метод. Динамически создает экземпляр массива любого типа, размерности и длины |
Теперь рассмотрим примеры использования описанных методов и свойств. В примерах выводимые данные записаны как комментарии. Вначале – использование нескольких простых элементов System.Array:
int[,] M = {{1, 3, 5}, {10, 20, 30}};
Console.WriteLine(M.Rank); // 2
Console.WriteLine(M.Length); // 6
Console.WriteLine(M.GetLowerBound(0)); // 0
Console.WriteLine(M.GetUpperBound(1)); // 2
Продемонстрируем сортировку и поиск в одномерном массиве:
int[] M = {1, -3, 5, 10, 2, 5, 30};
Console.WriteLine(Array.IndexOf(M, 5)); ); //2
Console.WriteLine(Array.LastIndexOf(M, 5)); //5
Array.Reverse(M);
foreach(int a in M)
Console.WriteLine(a); //30, 5, 2, 10, 5, -3, 1
Array.Sort(M);
foreach(int a in M)
Console.WriteLine(a); //-3, 1, 2, 5, 5, 10, 30
Console.WriteLine(Array.BinarySearch(M, 10)); //5
Опишем процесс динамического создания массива. Данный способ позволяет задать для массивов произвольные нижние и верхние границы. Допустим, нам необходим двумерный массив из элементов decimal, первая размерность которого представляет годы в диапазоне от 1995 до 2004, а вторая – кварталы в диапазоне от 1 до 4. Следующий код осуществляет создание массива и обращение к элементу массива:
//Назначение этих массивов понятно из их названий
int[] LowerBounds = {1995, 1};
int[] Lengths = {10, 4};
//"Заготовка" для будущего массива
decimal[,] Target;
Target = (decimal[,])Array.CreateInstance(typeof(decimal),
Lengths,LowerBounds);
//Пример обращения к элементу
Target[2000, 1] = 10.3M;
Допустимо было написать код для создания массива без приведения типов. Однако в этом случае для установки и чтения элементов необходимо было бы использовать методы SetValue() и GetValue():
Array Target;
Target = Array.CreateInstance(typeof(decimal), Lengths,
LowerBounds);
Target.SetValue(10.3M, 2000, 1);
Console.WriteLine(Target.GetValue(2000, 1));
Работа с элементами массива, созданного при помощи CreateInstance(), происходит медленнее, чем работа с «обычным» массивом.