|
Прошел курс. Получил код 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();
}
}
}

