Учебно-методический комплекс общее количество часов 58 ч. Лекции 28 ч


Download 2.46 Mb.
bet41/91
Sana19.10.2023
Hajmi2.46 Mb.
#1709453
TuriУчебно-методический комплекс
1   ...   37   38   39   40   41   42   43   44   ...   91
Bog'liq
Язык программирования C#

8.5. Индексаторы

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


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

спецификатор доступа тип0 this[тип1 пар1, тип2 пар2,…, типN парN]


{
спецификатор доступа set
{
}

спецификатор доступа get


{
return значение;
}
}

Если индексатор доступен только для чтения, блок set следует опустить.


спецификатор доступа тип0 this[тип1 пар1, тип2 пар2,…, типN парN]


{
спецификатор доступа get
{
return значение;
}
}
Если индексатор доступен только для записи, то следует опустить блок get.

спецификатор доступа тип0 this[тип1 пар1, тип2 пар2,…, типN парN]


{
спецификатор доступа set
{
}
}

В этой схеме: тип0 – тип, возвращаемый индексатором; тип1, тип2,…,типN – типы формальных параметров, принимаемых индексатором; пар1, пар2,…,парN – имена формальных параметров. Спецификатор доступа можно опустить, тогда буде использован спецификатор по умолчанию private. Индексаторы не могут быть статическими так, как они задумывались исключительно для работы с объектами классов, а не с самими классами.


Индексатор должен принимать хотя бы один параметр, иначе обращение к нему нельзя будет отличить от обращения к объекту.
Индексаторы – это еще один удобный способ записи функций, поэтому индексаторы можно подобно функциям перегружать.
class SampleCollection
{
private int[] arr = new int[100];
public int this[int i]
{
get
{
return arr[i];
}
set
{
arr[i] = value;
}
}
}
Лист. 8.19

Приведем нестандартный пример с перегрузкой индексаторов для доступа к двумерному массиву вещественных чисел.


class DoubleMatrixAccess


{
// поле, хранящее матрицу
private double[, ] Matrix;

// конструктор класса


public DoubleMatrixAccess(int M, int N)
{
Matrix = new double[M, N];
}

// свойство для доступа к количеству строк матрицы


public int M
{
get
{
return (Matrix.GetLength(0));
}
}

// свойство для доступа к количеству столбцов матрицы


public int N
{
get
{
return (Matrix.GetLength(1));
}
}

// индексатор для доступа к элментам матрицы


public double this[int i, int j]
{
set
{
if (i >= M || j >= N || i < 0 || j < 0)
{
Console.WriteLine("Ошибка: Выход за границы
массива.");
return;
}

Matrix[i, j] = value;


}

get
{


if (i >= M || j >= N || i < 0 || j < 0)
{
Console.WriteLine("Ошибка: Выход за границы
массива.");
return 0;
}

return Matrix[i, j];


}
}

// индексатор для доступа к элментам матрицы


public double this[string i, string j]
{
set
{
int IntI, IntJ;
if (!Int32.TryParse(i, out IntI)|| !
Int32.TryParse(j, out IntJ))
{
Console.WriteLine("Ошибка: Неверное представление
числа.");
return;
}

if (IntI >= M || IntJ >= N || IntI < 0 || IntJ < 0)


{
Console.WriteLine("Ошибка: Выход за границы
массива.");
return;
}

Matrix[IntI, IntJ] = value;


}

get
{


int IntI, IntJ;
if (!Int32.TryParse(i, out IntI) ||
!Int32.TryParse(j, out IntJ))
{
Console.WriteLine("Ошибка: Неверное представление
числа.");
return 0;
}

if (IntI >= M || IntJ >= N || IntI < 0 || IntJ < 0)


{
Console.WriteLine("Ошибка: Выход за границы
массива.");
return 0;
}

return Matrix[IntI, IntJ];


}
}
}
Лист. 8.20

В приведенном листинге определен класс DoubleMatrixAccess, у этого класса только одно private поле, представленное двумерным массивом вещественных чисел double[] Matrix, и единственный конструктор, ожидающий два параметра типа int, определяющих размер массива Matrix.


В классе DoubleMatrixAccess определены два public свойства для доступа к размерностям матрицы Matrix: свойство M типа int возвращает число строк массива, свойство N типа int возвращает число столбцов массива.
В классе DoubleMatrixAccess определены два индексатора для доступа к матрице Matrix. Оба индексатора получают в качестве параметров координаты элемента матрицы, к которому мы хотим обратиться и если координаты, переданные индексатору, не выходят за границы массива, то мы можем получить или изменить нужный элемент, иначе индексатор сообщает об ошибке. Единственная разница между индексаторами состоит в том, что один из них ожидает координаты в числовой форме, а другой ожидает текстовое представление, предаваемых ему координат и уже сам переводит текстовое представления числа в само число.

Создадим теперь программу для тестирования класса DoubleMatrixAccess.


class Program


{
static void Main(string[] args)
{
DoubleMatrixAccess Matrix = new DoubleMatrixAccess(10, 10);

// пытаемся обратиться к несуществующим элментам массива


Matrix[10, 10] = 1;
Matrix[11, 11] = 100;

Matrix[10.ToString(), 10.ToString()] = 0;


Matrix["7", "11"] = 0;

// инициалиизируем массив


for (int i = 0; i < Matrix.M - 5; i++)
for (int j = 0; j < Matrix.N; j++)
Matrix[i, j] = i + j;

for (int i = Matrix.M - 5; i < Matrix.M; i++)


for (int j = 0; j < Matrix.N; j++)
Matrix[i.ToString(), j.ToString()] = i + j;

// выводим массив


for (int i = 0; i < Matrix.M - 5; i++)
{
for (int j = 0; j < Matrix.N; j++)
Console.Write(Matrix[i, j] + "\t");
Console.WriteLine();
}

for (int i = Matrix.M - 5; i < Matrix.M; i++)


{
for (int j = 0; j < Matrix.N; j++)
Console.Write(Matrix[i.ToString(), j.ToString()] + "\t");
Console.WriteLine();
}
}
}
Лист. 8.21

В первой строчке приведенной программы создается объект Matrix класса DoubleMatrixAccess, конструктору класса передаются две размерности поля Matrix этого класса, при создании массива все его элементы обнуляются.


Далее в двух циклах в класс Matrix заносятся значения элементов массива, в первом цикле используется числовой индексатор во втором строковой.
Затем также в двух циклах элементы массива выводятся из Matrix, в первом цикле используется числовой индексатор во втором строковой.
Вывод программы:

Ошибка: Выход за границы массива.


Ошибка: Выход за границы массива.
Ошибка: Выход за границы массива.
Ошибка: Выход за границы массива.
0 1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9 10


2 3 4 5 6 7 8 9 10 11


3 4 5 6 7 8 9 10 11 12


4 5 6 7 8 9 10 11 12 13


5 6 7 8 9 10 11 12 13 14


6 7 8 9 10 11 12 13 14 15


7 8 9 10 11 12 13 14 15 16


8 9 10 11 12 13 14 15 16 17


9 10 11 12 13 14 15 16 17 18


Вывод. 8.7

Индексаторы являются всего лишь удобным средством записи экземплярные методов. Следовательно, для индексаторов не требуются связанные с ними массивы, но благодаря индексаторам можно эмулировать массивы. Фактически определенные таким образом индексаторы перегружают оператор “[]”, перегрузить который в C# явно невозможно.


Для примера создадим логическую матрицу, элементы которой равны произведению номера строки и столбца, на которых они находятся.
class LogicalMatrix
{
public int this[int i, int j]
{
get
{
return i *j;
}
}
}
Лист. 8.22

Единственным членом приведенного класса LogicalMatrix является индексатор, возвращающий произведение переданных ему чисел.


Напишем теперь программу для тестирования класса LogicalMatrix.


class Program
{
static void Main(string[] args)
{
LogicalMatrix Matrix = new LogicalMatrix();
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
Console.Write(Matrix[i, j] + "\t");
Console.WriteLine();
}
}
}
Лист. 8.23

Это программа сначала создает “матрицу” LogicalMatrix, а затем выводит все её элементы.


Вывод программ:
0 0 0 0 0 0 0 0 0 0

0 1 2 3 4 5 6 7 8 9


0 2 4 6 8 10 12 14 16 18


0 3 6 9 12 15 18 21 24 27


0 4 8 12 16 20 24 28 32 36


0 5 10 15 20 25 30 35 40 45


0 6 12 18 24 30 36 42 48 54


0 7 14 21 28 35 42 49 56 63


0 8 16 24 32 40 48 56 64 72


0 9 18 27 36 45 54 63 72 81


Вывод. 8.8

Download 2.46 Mb.

Do'stlaringiz bilan baham:
1   ...   37   38   39   40   41   42   43   44   ...   91




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling