Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет: Срок действия этого кода проверки уже истек. Проверьте, правильно ли введен код. У вас осталось две попытки. Вы также можете выбрать другой способ проверки или предоставить соответствующие документы, подтверждающие ваш академический статус.
Как активировать код? |
Контролирующий код C#
Индексаторы
Создание объектов с контролирующим кодом, имитирующих работу массивов, является главной целью индексаторов. Существующий массив может упаковываться в поле класса, а один из общедоступных методов класса, который и называется индексатором, допускает форму вызова через объект класса по синтаксису массива. Индексаторы, как и массивы, бывают одномерными и многомерными.
Одномерный индексатор задается по следующему синтаксису:
// Одномерный индексатор - специфический метод класса тип_элемента this[int индекс] { // Аксессор чтения get { // Возврат значения, // заданного элементом "индекс" } // Аксессор записи set { // Установка значения для элемента, // адресуемого с помощью "индекс" } }
Тип_элемента устанавливает тип индексируемых элементов, доступ к которым предоставляет индексатор. При использовании индексатора аксессоры вызываются автоматически и могут использовать значение индекс. Если индексатор стоит слева от оператора присваивания, то срабатывает аксессор set, которому передается в переменной value значение выражения для присваивания, стоящего справа. Если индексатор стоит справа от оператора присваивания, то срабатывает аксессор get, который должен вернуть какое-то значение переменной, стоящей слева. Фактически это то же самое, что и функции доступа, только используется синтаксис массивов.
Многомерный индексатор отличается от одномерного только тем, что вместо единственного индекса имеет список индексов, например, три индекса. Индексаторы должны быть объявлены с модификатором publi c, чтобы быть доступными во внешнем коде.
// Многомерный индексатор тип_элемента this[int индекс1, int index2, int index3] { // Аксессор чтения get { // Что-то делаем, используя индексы, // и возвращаем единственное значение } // Аксессор записи set { // Что-то делаем, используя индексы } }
// Файл Program.cs using System; class MyClass { public MyClass() { // Настройка консоли Console.Title = "Использование индексаторов"; Console.ForegroundColor = ConsoleColor.White; Console.CursorVisible = false; // Создаем объект класса, инкапсулирующего целочисленный массив const int SIZE = 4; ControlBordersArray arrayControl = new ControlBordersArray(SIZE); // Наполняем значениями for (int i = 0; i < arrayControl.Length; i++) arrayControl[i] = i + 1; // Печатаем исходный Console.WriteLine("Исходный массив:"); for (int i = 0; i < arrayControl.Length; i++) Console.Write("{0, -3}", arrayControl[i]); // Перевод на новую строку и пустая строка Console.WriteLine(Environment.NewLine); // Адресуемся за границы внутреннего массива arrayControl[-5] = 20; arrayControl[5] = 30; // Опять печатаем Console.WriteLine("Измененный массив:"); for (int i = 0; i < arrayControl.Length; i++) Console.Write("{0, -3}", arrayControl[i]); } } // Упаковка массива в класс class ControlBordersArray { // Закрытые поля класса int[] array; // Ссылка на одномерный массив int length; // Длина массива // Конструктор с параметрами public ControlBordersArray(int size) { length = size; // Установили параметр длины array = new int[length]; // Создали одномерный массив } // Конструктор по умолчанию public ControlBordersArray() { length = 16; // Установили параметр длины array = new int[length]; // Создали одномерный массив } // Публичное свойство только для чтения public int Length { get { return length; } } // Публичный метод - индексатор // При выходе индекса за границы работать с пограничными элементами public int this[int index] { get { if (index < 0) return array[0]; else if (index >= length) return array[length - 1]; else return array[index]; } set { if (index < 0) array[0] = value; else if (index >= length) array[length - 1] = value; else array[index] = value; } } } class Program { static void Main() { new MyClass();// Чтобы сработал конструктор // Для задержки консольного окна Console.ReadLine(); } }
Приведенный пример демонстрирует создание контролирующего границы кода при работе с элементами упакованного в класс массива. Но базового массива внутри класса может и не быть, а значения якобы хранящихся элементов массива фактически будут при каждом обращении вычисляться на лету. Конечно, индексатор для этого случая должен использоваться только для чтения без аксессора set.
В качестве примера приведем класс с двумя перегруженными индексаторами, один из которых на лету генерирует элементы таблицы умножения, другой - квадраты чисел. Какой индексатор присоединить в вызывающем коде, решает компилятор по сигнатуре индексатора (в нашем случае - по числу параметров). Также приведем метод, функциональность которого эквивалентна индексатору, только его применение построено в ином - традиционном синтаксисе.
// Файл Program.cs namespace Test { using System; // Инструкция может быть и внутри пространства имен class MyClass { public MyClass() { // Настройка консоли Console.Title = "Использование индексаторов"; Console.ForegroundColor = ConsoleColor.White; Console.CursorVisible = false; // Создаем объект таблицы умножения MultiplicationTable table = new MultiplicationTable(); string str; // Используем многомерный индексатор // и распечатываем таблицу умножения Console.WriteLine("Таблица умножения по индексатору"); for (int i = table.MinValue; i <= table.MaxValue; i++) { str = ""; for (int j = table.MinValue; j <= table.MaxValue; j++) str += String.Format("{0}x{1}={2, -3} ", i, j, table[i, j]); Console.WriteLine(str); } // Используем перегруженный одномерный индексатор // и распечатываем квадраты чисел Console.WriteLine(Environment.NewLine + "Квадраты первых чисел натурального ряда"); str = ""; for (int i = table.MinValue; i <= table.MaxValue; i++) str += String.Format("{0}x{0}={1, -3} ", i, table[i]); Console.WriteLine(str); // Используем метод и распечатываем таблицу умножения Console.WriteLine("\r\nТаблица умножения по методу"); for (int i = table.MinValue; i <= table.MaxValue; i++) { str = ""; for (int j = table.MinValue; j <= table.MaxValue; j++) str += String.Format("{0}x{1}={2, -3} ", i, j, table.Get(i, j)); Console.WriteLine(str); } } } // Имитация таблицы умножения class MultiplicationTable { // Свойства public int MinValue { get { return 1; } } public int MaxValue { get { return 9; } } // Публичный индексатор // имитирующий элементы таблицы умножения public int this[int index1, int index2] { get { int indexMin = Math.Min(index1, index2); int indexMax = Math.Max(index1, index2); if (indexMin >= MinValue && indexMax <= MaxValue) return index1 * index2; else { Console.WriteLine("Это уже высшая математика"); return 0; } } } // Обычный метод // Код точно такой, что и в многомерном индексаторе public int Get(int index1, int index2) { int indexMin = Math.Min(index1, index2); int indexMax = Math.Max(index1, index2); if (indexMin >= MinValue && indexMax <= MaxValue) return index1 * index2; else { Console.WriteLine("Это уже высшая математика"); return 0; } } // Перегруженный индексатор, возвращающий квадраты чисел public int this[int index] { get { if (index >= MinValue && index <= MaxValue) return index * index; else { Console.WriteLine("Это уже высшая математика"); return -1; } } } } class Program { static void Main() { new MyClass();// Чтобы сработал конструктор // Для задержки консольного окна Console.ReadLine(); } } }