Learning C# and OOP, Indexers, Part 2
Baldwin applies indexers to the simple Radio program discussed in an earlier lesson.
Published: November 3, 2002
C# Programming Notes # 108b
This lesson is part of a miniseries designed to teach you how to write object-oriented programs using C#. The first lesson in the miniseries was entitled Learning C# and OOP: Getting Started, Objects and Encapsulation. The previous lesson was entitled Learning C# and OOP, Indexers, Part 1.
No prerequisite C# or OOP knowledge required
The miniseries assumes no prerequisite knowledge of C# syntax or OOP concepts. If you have a general understanding of computer programming, you should be able to read and understand the lessons in this miniseries.
You may find it useful to open another copy of this lesson in a separate browser window. That will make it easier for you to scroll back and forth among the different listings while you are reading about them.
I recommend that you also study the other lessons in my extensive collection of online programming tutorials. You will find a consolidated index at www.DickBaldwin.com.
In previous lessons, you learned about the use of simple properties and indexed properties in both C# and Java. You learned that the most important aspect of properties in both programming environments is their use in reflection in C# and introspection in Java. I showed you an example of those processes in both languages.
An indexed property is a property that is capable of storing more than one value based on an index, and is capable of returning any of the values associated with a specific index.
Indexers and classes
A previous lesson entitled Learning C# and OOP, Classes, developed a simple C# program, which simulated the manufacture and use of the car radio. This lesson will revise the program from that previous lesson to incorporate the use of the C# indexers.
Manufacture and use of a car radio
As before, a simple C# program will be discussed to illustrate the definition and use of two different classes. Taken in combination, these two classes simulate the manufacture and use of a car radio.
Create a new Radio object
You will see how to write code to create a new Radio object by applying the new operator to the class named Radio. You will also see how to save that object's reference in a reference variable of type Radio.
Program the car radio using an indexer
You will see how to write code that is used to simulate the association of a radio button with a particular radio station. The code used to accomplish this makes use of a C# indexer.
The plans for a car radio
You will see the definition of a class named Radio. This class includes an instance variable that refers to an array object. The array object is combined with some additional rather cryptic code to form an indexer.
You will see the definition of a class named Radio01a. This class consists solely of the Main method. The Main method of a C# program is executed by the C# Common Language Runtime (CLR) when the program is run. Thus, it is the driver for the entire program.
What is a class?
A class is a plan from which many objects can be created. I previously likened the class definition to the plans from which millions of nearly identical car radios can be produced.
The car radio example
Listing 6, near the end of the lesson shows the code for a simple C#
program named Radio01a.
Explain in fragments
In order to help you to focus specifically on important sections of code, I will explain the behavior of this program in fragments.
This program contains two top-level class definitions, Radio and Radio01a.
The Radio class
Listing 1 shows the entire class definition for the Radio class with
the material that is new to this lesson highlighted in boldface.
Setting a radio frequency
The code in the set block of Listing 1 is used to simulate the association of a particular button with a particular radio station by the user.
Two incoming parameters
The code in the set block in Listing 1 receives two incoming parameters (although they don't appear in the form of normal method parameters):
Save the frequency value
The code in the set block stores the frequency value in an element of the array object referred to by stationNumber. The element number is specified by the value of the index shown in square brackets in the assignment statement.
Very cryptic setter and getter constructs
As you can see, and as was explained in the previous lesson on indexers, this approach to setting and getting properties involves some very cryptic code, which is peculiar to C#.
As you will see later, it appears to the user that setter and getter methods are not being invoked when property values are being set and retrieved. However, as you can see from Listing 1, there is code inside the set and get blocks that is being invoked.
Validation code can be used if needed
This makes it possible for the programmer of the Radio class to insert validation code inside the set and get blocks shown in Listing 1, if needed.
For example, if I had intended for this to be a robust program, I probably would have put code in the set and get blocks to confirm that the incoming index was within the bounds of the array referred to by the reference variable named stationNumber.
I might also have inserted code in the set block to confirm that the incoming frequency value is a valid frequency value (for example, a valid frequency value cannot be negative).
The remaining code
The remaining code in the Radio class is the same as was discussed in the program named Radio01 in a previous lesson. Therefore, I won't discuss it further in this lesson.
The class named Radio01a
The class named Radio01a is shown in its entirety in Listing
2. An object of this class simulates the manufacturer and the user
of the radio object.
Concentrate on code that is different
Most of the code in Listing 2 is identical to that discussed in a previous lesson for the program named Radio01. Therefore, I will concentrate on those aspects of this program that are different from the previous program. In particular, I will emphasize the use of the indexer to store the radio station frequencies in this program.
The class named Radio01a consists solely of the Main method. The Main method of a C# program is executed by the C# CLR when the program is run. Thus, it is the driver for the entire application.
The driver class
An object instantiated from the code in Listing 2 simulates the manufacturer of the radio and the use of the radio by the end user.
Without getting into a lot of detail regarding C# syntax, I will further subdivide and discuss this code in the following fragments.
Constructing a Radio object
As discussed in a previous lesson, the code in Listing 3 applies the
operator to the constructor for the Radio class, causing a new object
to be created according to the plans specified in the class named Radio.
Saving a reference to the Radio object
Also as discussed in a previous lesson, the code in Listing 3 declares a reference variable named myRadio, of type Radio, and stores the new object's reference in that variable.
Programming the radio buttons
The code in Listing 4 is new to this program. This statement simulates the process of associating a particular radio station with a particular button on the front of the radio.
Invoking a setter method
The statement from the previous program, (shown as a comment in Italics in Listing 4), associates a simulated frequency selector button with a simulated radio station. This is accomplished by invoking the method named setStationNumber on the reference to the Radio object.
This is a common approach to storing data in the instance variables of an object in C++ and Java. (It is also a design pattern for an indexed property in Java.)
Also works fine in C#
This approach also works just fine in C#, but the designers of C# came up with an alternative way to set property values in C#.
Something is happening behind the scenes
The non-Italic statement in Listing 4 shows the special syntax used to set the value of an indexer in C#.
Looks like an assignment to an array object
As you can see, it appears to the user that this syntax doesn't entail the invocation of a setter method. The statement appears simply to be the assignment of a double value to an array element at index 3.
The reference to the Radio object is being treated as though the object is an array object, even though it wasn't declared as such.
Button 3 associated with frequency of 93.5
The code in Listing 4 causes radio button number 3 to be associated with the frequency 93.5 MHz. (The value 93.5 is stored in the indexer element that represents button number 3.)
Illustrate the get side of the indexer
Just to illustrate the get side of the indexer, the
code in Listing 5 gets and displays the frequency value stored in the indexer at index 3. (This
is somewhat analogous to the display on my car radio, but the analogy is very
The important part of the code in Listing 5 is highlighted in boldface.
Appears to access an array element
Again, it appears that this code simply accesses an element in an array at index 3, and that the get operation doesn't entail the invocation of a getter method. However, as we saw earlier, code in a get block is actually invoked behind the scenes.
The code in Listing 5 produces the following output on the screen.
Button 3 frequency is 93.5 Mhz
The remaining code in the Radio01a class is identical to the code that I discussed in the program named Radio01 in a previous lesson. Therefore, I am going to skip the remaining code.
This lesson has concentrated primarily on a discussion of the C# class and a C# indexer.
A simple C# program was discussed to illustrate the definition and use of two different classes. Taken in combination, these two classes simulate the manufacture and use of the car radio object discussed in an earlier lesson.
You saw how to write code to create a new Radio object by applying the new operator to the constructor for the class named Radio. You also saw how to save that object's reference in a reference variable of type Radio.
You saw how to write code using an indexer to simulate the association of a radio button with a particular radio station.
You saw the definition of the class named Radio01a, which consists solely of the Main method. The Main method of a C# program is executed by the C# Common Language Runtime (CLR) when the program is run.
You saw the definition of the class named Radio. This class includes an instance variable that refers to an array object. The array object is combined with some additional cryptic code to form an indexer.
A complete listing of the program is shown in Listing 6.
Copyright 2002, Richard G. Baldwin. Reproduction in whole or in part in any form or medium without express written permission from Richard Baldwin is prohibited.
Richard Baldwin is a college professor (at Austin Community College in Austin, Texas) and private consultant whose primary focus is a combination of Java, C#, and XML. In addition to the many platform and/or language independent benefits of Java and C# applications, he believes that a combination of Java, C#, and XML will become the primary driving force in the delivery of structured information on the Web.
Richard has participated in numerous consulting projects and he frequently provides onsite training at the high-tech companies located in and around Austin, Texas. He is the author of Baldwin's Programming Tutorials, which has gained a worldwide following among experienced and aspiring programmers. He has also published articles in JavaPro magazine.
© 1996, 1997, 1998, 1999, 2000, 2001, 2002 Richard G. Baldwin