property instance class SimpleIndexer.Car Item(int32) {
.get instance class SimpleIndexer.Car SimpleIndexer.Garage::get_Item(int32)
.set instance void SimpleIndexer.Garage::set_Item(int32, class SimpleIndexer.Car)
} // end of property Garage::Item
Методы get_Item() и set_Item() будут реализованы аналогично любому другому свойству .NET, например:
method public hidebysig specialname instance сlass SimpleIndexer.Car get_Item(int32 pos) cil managed {
Code size 22 (0x16)
.maxstack 2
.locals init ([0] class SimpleIndexer.Car CSS1$0000)
IL_0000: ldarg.0
IL_0001: ldfld class [mscorlib] System.Collections.ArrayList SimpleIndexer.Garage::carArray
IL_0006: ldarg.1
IL_0007: callvirt instance object [mscorlib] Sysftem.Collections.ArrayList::get_Item(int32)
IL_000c: castclass SimpleIndexer.Car
IL_0011: stloc.0
IL_0012: br.s IL_0014
IL_0014: ldloc.0
IL_0015: ret
} // end of method Garage::get_Item
Заключительные замечания об индексаторах
Чтобы получить настоящую экзотику, вы можете создать индексатор, который имеет множество параметров. Предположим, что у нас есть пользовательская кол-лекция, которая хранит элементы в двумерном массиве. В этом случае вы можете создать метод индексатора, доказанный ниже.
public class SameContainer {
private int[,] my2DinArray = new int[10, 10];
public int this[int row, int column] {/* прочитать или установить значение 2D-массива * /}
}
В заключение следует заметить, что индексаторы могут определяться и для типа интерфейса .NET, что обеспечивает реализующим интерфейс типам возможность его настройки. Вот пример такого интерфейса.
public interface IEstablishSubObjects {
// Этот интерфейс определяет индексатор , возвращающий
// строки на основе числового индекса.
string this[int index] {get; set;}
}
Пожалуй, об индексаторах C# уже сказано достаточно. Перейдем к рассмотрению еще одного подхода, используемого в некоторых (но не во всех) языках программирования .NET: это перегрузка операций.
В C#, как и в любом другом языке программирования, есть свой ограниченный набор лексем, используемых для выполнения базовых операций со встроенными типами. Так, вы знаете, что операция + применима к двум целым числам и в результате дает их сумму.
// Операция + с целыми числами.
int а = 100;
int b = 240;
int с = а + b; // с теперь равно 340
Снова заметим, что это не новость, но вы, наверное, заметили и то, что одна и та же операция + может применяться к большинству встроенных типов данных C#. Рассмотрите, например, следующий фрагмент программного кода.
// Операция + со строками.
string s1 = "Hello";
string s2 = " world!";
string s3 = s1 + s2; // s3 теперь равно "Hello world!"
По сути, операция + функционирует уникальным образом в зависимости от поставляемых типов данных (в данном случае это строки или целые числа). Когда операция + применяется к числовым типам, результатом является сумма операндов, а когда операция + применяется к строковым типам, результатом будет конкатенация строк.
Язык C# обеспечивает возможность построения пользовательских классов и структур, которые будут по-своему отвечать на один и тот же набор базовых лексем (таких, как операция +). При этом следует заметить, что можно "перегружать" не все встроенные операции C#. В табл. 9.1 указаны возможности перегрузки базовых операций.
Таблица 9.1.Возможности перегрузки операций
Операции C# |
Возможность перегрузки |
+, -, !, ~, ++, --, true, false |
Эти унарные операции допускают перегрузку |
+, -, *, /, %, &, |, ^, ‹‹, ›› |
Эти бинарные операции допускают перегрузку |
==, !=, ‹, ›, ‹=, ›= |
Операции сравнения допускают перегрузку. В C# требуется, чтобы перегрузка "родственных" операций (т.е. ‹ и ›, ‹= и ›=, == и !=) выполнялась одновременно |
[] |
Операция [] не допускает перегрузку. Но, как было показано выше, аналогичные перегрузке возможности обеспечивает конструкция индексатора |
() |
Операция () не допускает перегрузку. Но, как будет показано ниже, аналогичные перегрузке возможности обеспечивают пользовательские методы преобразования |
+=, -=, *=, /=, %=, &=, |=, ^=, ‹‹=, ››= |
Операторные сокращения с присваиванием сами по себе не допускают перегрузку, однако для них перегруженная форма получается автоматически в результате перегрузки соответствующей бинарной операции |
Перегрузка бинарных операций
Чтобы проиллюстрировать процесс перегрузки бинарных операций, расcмо-трим следующую простую структуру Point (точка).
Читать дальше