Making Classes Behave Like Arrays (Adding Indexers)


Imagine that you're writing your own grid WebControl (it's the kind of thing I like to do for fun on the weekends). A grid control is a visual element that displays data in tabular form on a WebForm or on a WinForm. Let's say that your class name is CodeGrid. CodeGrid has a field that stores a twodimensional array: It stores information in terms of rows and columns . A client may use your class as follows : CodeGrid cg = new CodeGrid(5,4); specifying that they want to create a grid of five rows by four columns. Then the client would want to set the elements of a cell , say R2,C1. How would they do that? One way is to just provide a function like SetItem(int Row, int Column, int Value) in which they can specify the Row, the Column, and then the Value for the cell. But a more elegant way is to provide an indexer. This is a property that makes the class look as if it were an array. The indexer would enable the programmer to set a cell in this fashion: cg[2,1] = 45; .

To add an indexer to your class:

  1. An indexer is similar to a property declaration. Begin by typing an access modifier, for example: public .

  2. Type a return value for the indexer, for example: string .

  3. Type this .

  4. Type an open square bracket [;

  5. Type the parameters for the indexer. In the case of my grid control example the parameters would be: int Row, int Column .

  6. Type a close square bracket ] .

  7. Type an open curly bracket { .

  8. Type get .

  9. Type an open curly bracket { .

  10. Return a value of the type you specified in step 2. In the case of the grid example in which items are stored in a twodimensional array, you would write: return m_storage[Row,Column]; .

  11. Type a close curly bracket } .

  12. Type set .

  13. Type an open curly bracket { .

  14. Type code that stores the value received from the programmer using the indexer. You can reference the value using the value keyword. In the case of the grid example, you would write: m_storage[Row,Column] = value; .

  15. Type a close curly bracket } .

  16. Type another close curly bracket } ( Figure 9.45 ).

    Figure 9.45 An indexer gives users the illusion that your tic-tac-toe board is an array of spaces.
     class TicTacToeBoard {    string[,] spaces = new string[3,3];    public string this[int x, int y]    {       get       {          return spaces[x,y];       }       set       {          spaces[x,y] = value;       }    } } void Task() {    TicTacToeBoard board = new TicTacToeBoard();    board[1,1] = "O";    board[1,2] = "X"; } 

graphics/tick.gif Tips

  • Indexers can also be read-only or writeonly if you omit either the set or the get portion.

  • In essence, an indexer is a property. When you look at the class with an indexer from another language like VB.NET, the Indexer appears as a property called Item. In fact, you can change the name of the resulting property from Item to something else by applying the System.Runtime.CompilerServices.IndexerName attribute to your class ( Figure 9.46 ).

    Figure 9.46 By default, the name of the Indexer is Item, although in C# you can't reach the indexer by using Item as a property. This code changes the name to Squares. In Languages like Visual Basic .NET you would then be able to write board.Squares(2,2) = "X" which is more intuitive than board.Items(2,2).
     class TicTacToeBoard {    string[,] spaces = new string[3,3];  [System.Runtime.CompilerServices.   IndexerName("Square")]  public string this[int x, int y]    {       get       {          return spaces[x,y];       }       set       {          spaces[x,y] = value;       }    } } void Task() {    TicTacToeBoard board =    new TicTacToeBoard();    board[1,1] = "O";    board[1,2] = "X"; } 



C#
C# & VB.NET Conversion Pocket Reference
ISBN: 0596003196
EAN: 2147483647
Year: 2003
Pages: 198
Authors: Jose Mojica

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net