The operator [] may be overloaded using an indexer. An indexer is similar to a property. Indexers may be multidimensional. Beginning with a single dimensional indexer, we have the following syntax.

operator[index] { get { // return the value at index } set { // set the value at index } }

The **get** accessor should return the element at the index and
the **set** accessor should set the value at the given index.
When executing the **set** accessor, the value is defined by
the keyword **value**. Like for a property, the get and the set accessors
are called automatically when the indexer is used. When the indexer is
used to read from, the get accessor is called, when the indexer is used
to write to, the set accessor is used.

3d vectors have a, b and c components. It may be convenient to access these components through an indexer. The next program provides an indexer for 3d vectors.

// indexer_a - an example of an indexer. generic vector { a b c vector() { a = 0.0 b = 0.0 c = 0.0 } vector(aset bset cset) { a = aset b = bset c = cset } operator[n] { get { switch n { case 0 return a case 1 return b case 2 return c default throw "index out of range" } } set { switch n { case 0 a = value case 1 b = value case 2 c = value default throw "index out of range" } } } to_string() { return "(" + a.to_string() + "," + b.to_string() + "," + c.to_string() + ")" } } generic indexer_a { indexer_a() { u = new vector() u[0] = 1.0 u[1] = 2.0 u[2] = 3.0 s = "vector is: " + u.to_string() s.println() u[0] = u[2] + 1.0 s = "vector is: " + u.to_string() s.println() } }

The output is as follows.

vector is: (1,2,3) vector is: (4,2,3)

Often indexers are used to access an underlying array of some sort - but not always. For the above example, there is no underlying array- just a, b and c.

Matrices are an interesting class, but the general case is quite complex. So to get started with something managable, the beginnings of a special case will be examined - 2x2 matrices. This will allow us to explore multidimensional indexers with a serious example.

For multidimensional indexers, we have the following syntax.

operator[index1 index2 ... indexn] { get { // return the value at indices } set { // set the value at indices } }

The **get** accessor should return the element at the indices and
the **set** accessor should set the value at the given indices.
When executing the **set** accessor, the value is defined by
the keyword **value**.

The following example demonstrates a two dimensional indexer at work on a 2x2 matrix class.

// indexer_b - multidimensional indexers matrix22 generic matrix22 { a00 a01 a10 a11 matrix22() { a00 = 0.0 a01 = 0.0 a10 = 0.0 a11 = 0.0 } matrix22(i00 i01 i10 i11) { a00 = i00 a01 = i01 a10 = i10 a11 = i11 } matrix22(copy) { a00 = copy.a00 a01 = copy.a01 a10 = copy.a10 a11 = copy.a11 } operator[a b] { get { if a > 1 || b > 1 throw "index out of range" else if a == 0 { if b == 0 return a00 else return a01 } else { if b == 0 return a10 else return a11 } } set { if a > 1 || b > 1 throw "index out of range" else if a == 0 { if b == 0 a00 = value else a01 = value } else { if b == 0 a10 = value else a11 = value } } } } generic indexer_b { indexer_b() { c = new matrix22() m[0 0] = 1.0 m[0 1] = 2.0 m[1 0] = 3.0 m[1 1] = 4.0 a = m[0 0] b = m[0 1] c = m[1 0] d = m[1 1] s = "[" + a.to_string() + "," + b.to_string() + "," + c.to_string() + "," + d.to_string() + "]" s.println() } }

A 2x2 matrix has 4 elements often thought of as located in to row vectors. An element of a 2x2 matrix m is as follows

m_{a,b}, where 0 <= a,b <= 1

Zero based notation has been adopted. A couple of different internal representations of 2x2 matrices could be chosen. An array of 4 elements can be used or 4 individual fields can be used. For the above class, the later option is chosen. Irrespective of the internal representation of the matrices, the external interface is certainly a two dimensional indexer - as shown above. When the dimensions of the matrices are higher, the same two dimensional indexer interface is used. The above class is just the beginnings of a 2x2 matrix class. Many operators need to be added to complete the matrix algebra. The next chapter introduces operator overloading, and this class gets a major enhancement.