На этом шаге мы рассмотрим еще один пример индексатора с одним аксессором.
Еще один пример индексатора с одним аксессором представлен в следующей программе. Там у индексатора есть только set-аксессор. Рассмотрим приведенный ниже программный код.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace pr130_1 { // Класс с индексатором: class MyString { // Закрытое текстовое поле: private string text; // Конструктор с текстовым аргументом: public MyString(string t){ text = t; } // Операторный метод для неявного преобразования // текстового значения в объект класса MyString: public static implicit operator MyString(string t) { return new MyString(t); } // Переопределение метода ToString(): public override string ToString() { return text; } // Символьный индексатор с целочисленным индексом: public char this[int k] { // Метод вызывается при присваивании значения // выражению с индексированным объектом: set { // Проверка значения индекса: if (k < 0 || k >= text.Length) return; // Текстовая переменная: string t = ""; // Добавление символов к тексту: for(int i = 0; i < k; i++) { t += text[i]; } // Добавление в текст присваиваемого символа: t += value; // Добавление символов к тексту: for(int i = k + 1; i < text.Length; i++) { t += text[i]; } // Новое значение текстового поля: text = t; } } } // Класс с главным методом: class Program { // Главный метод: static void Main() { // Создание объекта: MyString txt = "Myxa"; // Проверка текста: Console.WriteLine(txt); // Попытка изменить символ в тексте: txt[-1] = 'Ы'; // Проверка текста: Console.WriteLine(txt); // Попытка изменить символ в тексте: txt[4] = 'Ъ'; // Проверка текста: Console.WriteLine(txt); // Изменение символа в тексте: txt[0] = 'С'; // Проверка текста: Console.WriteLine(txt); // Изменение символа в тексте: txt[1] = 'л'; // Проверка текста: Console.WriteLine(txt); // Изменение символа в тексте: txt[2] = 'o'; // Проверка текста: Console.WriteLine(txt); // Изменение символа в тексте: txt[3] = 'н'; // Проверка текста: Console.WriteLine(txt); // Задержка: Console.ReadLine(); } } }
Результат выполнения программы такой.
Рис.1. Результат выполнения программы
В этой программе мы создаем очень скромное подобие класса, предназначенного для работы с текстом. Описанный нами класс с индексатором называется MyString. У класса есть закрытое текстовое поле text и конструктор с текстовым аргументом (переданный конструктору аргумент присваивается значением текстовому полю объекта). Также мы описали операторный метод для неявного приведения типа string в тип MyString. Благодаря этому объектным переменным класса MyString можно присваивать текстовые значения. В результате будет создаваться новый объект класса MyString, а текстовое поле этого объекта определяется тем текстовым значением, которое присваивается объектной переменной.
Еще в классе MyString переопределен метод ToString(). Переопределен он таким образом, что результатом возвращается текст из поля text.
Индексатор, описанный в классе MyString, имеет целочисленный индекс, а в нем есть только set-аксессор. Поэтому проиндексированному объекту можно только присвоить значение. Поскольку индексатор описан как относящийся к типу char, то и присваиваться должно символьное значение.
При присваивании символьного значения выражению с проиндексированным объектом создается иллюзия того, что в текстовом поле объекта меняется значение символа с соответствующим индексом. Делается это так. Сначала с помощью условной конструкции проверяется значение индекса k. Условие
if (k < 0 || k >= text.Length) return;
t += value;
text = t;
В главном методе программы командой
MyString txt = "Myxa";
txt[-1] = 'Ы';
txt[4] = 'Ъ';
txt[0] = 'С'; txt[1] = 'л'; txt[2] = 'o';
txt[3] = 'н';
На следующем шаге мы закончим изучение этого вопроса.