Indexers. One-dimensional and multidimensional indexers. Indexers without basic array. Overloading Indexers
Contents
- 1. What is called an indexer? How are indexers used in programs? General form of the indexer declaration
- 2. Example of declaring a one-dimensional indexer that returns a value of type char
- 3. Example of declaring a one-dimensional indexer that returns an int value
- 4. An example of declaring a one-dimensional indexer in which an index takes the char type
- 5. Example of declaring a two-dimensional indexer
- 6. Example of declaring a three-dimensional indexer
- 7. What are the features of using indexers without a base array
- 8. An example of a declaration a class that contains an indexer, but does not contain a base array. Calculating the value of the n-th Fibonacci number
- 9. What is called an overload of indexers?
- 10. Example of a class declaration that uses overloaded indexers
- Related topics
Search other websites:
1. What is called an indexer? How are indexers used in programs? General form of the indexer declaration
The indexer is a tool of the C# language, which allows you to index the object as an array using rectangular brackets [ ].With the help of indexers, you can implement your own specialized arrays, which can be subject to various restrictions.
The indexers can be one-dimensional and multidimensional.
The general form of the indexer declaration in a certain class:
type this[type_index index] { get { // code that returns a value by index // ... } set { // code that sets a value by index // ... } }
where
- type – the type of indexer item;
- index – the index or the position of the item in array by which the item is accessed;
- type_index – type index (position) of the indexer. Typically this is int type. However, other types are allowed (for example, double, char);
- this – a reference to the class that implements the indexer;
- get, set – the accessors respectively for reading (get) the value of the item and the save (set) value in the item.
⇑
2. Example of declaring a one-dimensional indexer that returns a value of type char
A one-dimensional indexer corresponds to a one-dimensional array. The example declares the class CharArray containing the indexer.
// class that contains the indexer class CharArray { char[] A; // constructor public CharArray(int size) { if (size > 26) size = 26; A = new char[size]; for (int i = 0; i < size; i++) A[i] = (char)((int)'A' + i); } // implementation of indexer public char this[int index] { get // read at 'index' position { if ((index >= 0) && (index < A.Length)) return A[index]; else return 'A'; } set // save to 'index' position { if ((index>=0) && (index<A.Length)) A[index] = value; } } }
In the above code, an indexer is declared that returns the value of items of type char. Indexes values are of type int.
In the indexer, two accessors are implemented: get, set. In the body of the implementation of the accessors the correct indexes range is checked.
Using the class in another program code
... // using CharArray class CharArray cA = new CharArray(15); // array of 15 characters char c; c = cA[0]; // c = 'A' c = cA[3]; // c = 'D' c = cA[10]; // c = 'K' c = cA[14]; // c = 'O' c = cA[15]; // c = 'A' - access attempt beyond limits c = cA[30]; // c = 'A' - access attempt beyond limits cA[3] = 'Z'; c = cA[3]; // c = 'Z' cA[30] = 'X'; // it is allowed, but is blocked in the set {...} c = cA[30]; // c = 'A' ...
⇑
3. Example of declaring a one-dimensional indexer that returns an int value
The example implements a class that contains a one-dimensional indexer that returns a value of type int. The index type in the indexer is also int.
// class containing the indexer class IntArray { int[] Array; // array public IntArray(int size) { // allocate memory for an array Array = new int[size]; // zeroing of array for (int i = 0; i < size; i++) Array[i] = 0; } // indexer public int this[int index] { // accessors get { return Array[index]; } set { Array[index] = value; } } }
Using the IntArray class in another program code
// using the IntArray class IntArray iA = new IntArray(100); int i; int d; // filling the array values via the indexer for (i = 0; i < 100; i++) iA[i] = i * i + 1; d = iA[3]; // d = 10 d = iA[25]; // d = 626 iA[25] = 15; d = iA[25]; // d = 15
⇑
4. An example of declaring a one-dimensional indexer in which an index takes the char type
The index type in the indexer does not have to be an integer. You can also declare another type of index, for example double, char. But in this case, when using an internal array, you need to cast the index type to type int.
The following example demonstrates the use of the indexer in a class where the index value is a number of ‘char’ type. This example implements the calculation of the number of Latin characters ‘A’ .. ‘Z’ in a given string.
// class in which the index in the indexer is of type char class CharIndex { int[] Array; int Size; public CharIndex() { Size = 26; Array = new int[Size]; for (int i = 0; i < Size; i++) Array[i] = 0; } // indexer public int this[char symbol] { get { if ((symbol>='A') && (symbol<='Z')) return Array[(int)((int)symbol - (int)'A')]; return 0; } set { if ((symbol>='A') && (symbol<='Z')) Array[(int)symbol-(int)'A'] = value; } } }
As can be seen from the above code, in the get and set accessors, the Array index is cast to int type. However, from the program code, to the object of the class CharIndex you can access the index of the type ‘char’.
Using the class in another program code
// using the CharIndex class CharIndex cI = new CharIndex(); string s = "USING AN INDEXERS IN PROGRAMS"; int d; int i; char c; // counting the number of characters 'A' .. 'Z' for (i = 0; i < s.Length; i++) cI[s[i]]++; d = cI['U']; // d = 1 d = cI['A']; // d = 2 d = cI['N']; // d = 4 d = cI['I']; // d = 3
⇑
5. Example of declaring a two-dimensional indexer
In the example, a two-dimensional indexer is declared, which implements a two-dimensional array of double numbers.
// class that implements a two-dimensional indexer class TwoDimIndexes { double[,] A; // internal array int m, n; // array dimension // constructor public TwoDimIndexes(int _m, int _n) { m = _m; n = _n; A = new double[m, n]; for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) A[i, j] = 0; } // two-dimensional indexer public double this[int i, int j] { get { return A[i, j]; } set { A[i, j] = value; } } }
Using the TwoDimIndexes class in some program code
// using of TwoDimIndexes class TwoDimIndexes dI = new TwoDimIndexes(3, 5); double x; // array formation with indexer for (int i = 0; i < 3; i++) for (int j = 0; j < 5; j++) dI[i, j] = i * 2 + j; x = dI[1, 3]; // x = 1*2 + 3 = 5 x = dI[2, 0]; // x = 4
⇑
6. Example of declaring a three-dimensional indexer
A class that contains a three-dimensional indexer is declared
// class in which a three-dimensional indexer is declared class ThreeDimIndexes { double[, ,] M; // three-dimensional array int x, y, z; // array dimension // constructor public ThreeDimIndexes(int _x, int _y, int _z) { x = _x; y = _y; z = _z; // Allocate memory for array M M = new double[3, 4, 5]; } // three dimensional indexer public double this[int i, int j, int k] { get { bool fi, fj, fk; // checking for valid array index bounds fi = (i >= 0) && (i < x); fj = (j >= 0) && (j < y); fk = (k >= 0) && (k < z); if (fi && fj && fk) return M[i, j, k]; else return 0.0; } set { bool fi, fj, fk; // проверка на допустимые границы индексов массива fi = (i >= 0) && (i < x); fj = (j >= 0) && (j < y); fk = (k >= 0) && (k < z); if (fi && fj && fk) M[i, j, k] = value; else M[i, j, k] = 0.0; } } }
Using a class in another program code
// using the ThreeDimIndexes class ThreeDimIndexes dI = new ThreeDimIndexes(3, 4, 5); double x; // generation of values of elements of an array with the help of an indexer int i, j, k; for (i = 0; i < 3; i++) for (j = 0; j < 4; j++) for (k = 0; k < 5; k++) dI[i, j, k] = i * 2.5 + j * 2 + k; x = dI[0, 1, 3]; // x = 0*2.5 + 1*2 + 3 = 5.0 x = dI[1, 3, 2]; // x = 1*2.5 + 3*2 + 2 = 10.5
⇑
7. What are the features of using indexers without a base array
In a class, you do not need to declare an internal array variable in order to use the indexer. Of course, the data can also be stored in an internal variable (array). However, there are cases when the value of the elements of the array are formed programmatically, that is, they are amenable to some regularity or formula. In these cases, it is not necessary to declare an internal array, for which additional memory is needed.
⇑
8. An example of a declaration a class that contains an indexer, but does not contain a base array. Calculating the value of the n-th Fibonacci number
In the CFibonacci class, an indexer is declared that forms the Fibonacci number based on its position in the series. To determine the number, the class implements the private extra method GetNumber(). The class does not contain a constructor. The indexer in the class contains only one get accessor.
Implementation of the class is as follows
// A class that contains an indexer without using an internal array class CFibonacci { // internal method // calculates the value of the Fibonacci number at its index private int GetNumber(int index) { if (index < 0) return -1; int t = 0; if (index == 1) t = 1; if (index == 2) t = 1; if (index > 2) { int t1, t2; int i; t1 = t2 = 1; i = 2; while (i < index) // Fibonacci number calculation cycle { t = t1 + t2; t1 = t2; t2 = t; i++; } } return t; } // indexer public int this[int index] { get { return GetNumber(index); } } }
Using the CFibonacci class in another program code
// using an indexer without an internal base array CFibonacci cF = new CFibonacci(); int d; // read the Fibonacci number d = cF[5]; // d = 5 d = cF[7]; // d = 13 d = cF[10]; // d = 55
⇑
9. What is called an overload of indexers?
Overloading the indexer is the implementation of several indexers in the class that have different index types (for example, int, char, double).
In general, the implementation of this class looks like this:
class ClassName { ... public return_type this[type1 index] { // ... } public return_type this[type2 index] { // ... } ... public return_type this[typeN index] { // ... } ... }
where
- ClassName – the name of the class in which the overloaded indexer is declared;
- return_type – the type of the indexer item. This type is common to all overloaded indexers;
- type1, type2, …, typeN – the types of indexes named ‘index’.
⇑
10. Example of a class declaration that uses overloaded indexers
The CDoubleArray class demonstrates the use of an overloaded indexer
// A class that contains an overloaded indexer class CDoubleArray { double[] A; int length; public CDoubleArray(int _length) { length = _length; A = new double[length]; for (int i = 0; i < length; i++) // enter the arbitrary values into array A[i] = i * 2; } // overloaded indexer public double this[int index] { get { return A[index]; } set { A[index] = value; } } public double this[double index] { get { return A[(int)(index+0.5)]; } set { A[(int)(index+0.5)] = value; } } }
Using the CDoubleArray class in another program code
// using an overloaded indexer CDoubleArray dA = new CDoubleArray(10); double d; d = dA[3]; // d = 6 d = dA[3.3]; // d = 6 d = dA[3.5]; // d = 8 dA[4.7] = 1100; d = dA[5]; // d = 1100
⇑
Related topics
- One-dimensional arrays. Examples of solving problems on one-dimensional arrays. Arrays of structures. Arrays of classes
- Multidimensional arrays. Stepped arrays
- Properties. Accessors get, set. Examples of classes containing properties